PDA

View Full Version : QListView and custom Widgets



Spooky
10th May 2011, 17:16
I want to create a QListView that displays custom widgets inside. I use it to reorder these custom widgets (for instance by using a custom model like here (http://www.qtcentre.org/threads/23258-How-to-reorder-items-in-QListView?p=113023#post113023)) and they need to be widgets, because I want to have different QPushButtons inside them.

wysota mentioned in this post (http://www.qtcentre.org/threads/8660-Drawing-a-widget-in-QItemDelegate-s-paint-method?p=46333#post46333) that
You can have a real widget, but it's not worth it - it's too heavy right now (maybe when 4.4 is released this situation will change).What is the situation in 4.7, is it 'worth it' now?

Also I am not sure how to actually implement it the way I want it. From this tutorial (http://doc.qt.nokia.com/4.5/model-view-delegate.html#updating-the-editor-s-geometry) I know how I would create custom Widgets in order to edit Model data, but in my case, the custom widget should always be displayed inside the QListView (and not just when an item is edited).

Santosh Reddy
10th May 2011, 17:33
Yes, you can do it.

It will be cost you more time to do it with QListView, but this is recommended if you are planning to have different types of custom Widgets in the ListView.

If you plan to have just couple of custom widgets, you are try using QListWidget, which should be quick and simple.

Yes indeed it is possible to display your custom widget inside the ListView in list item display mode and even in list item editing mode, it possible with both QListView and QListWidget.

Spooky
10th May 2011, 17:41
Yes, you can do it.

It will be cost you more time to do it with QListView, but this is recommended if you are planning to have different types of custom Widgets in the ListView.

If you plan to have just couple of custom widgets, you are try using QListWidget, which should be quick and simple.

Yes indeed it is possible to display your custom widget inside the ListView in list item display mode and even in list item editing mode, it possible with both QListView and QListWidget.Actually, for the time being, it would be just one custom Widget, not different types of custom Widgets. But why would it be easier then wiht a QListWidget instead of a QListView?

Santosh Reddy
10th May 2011, 17:59
For using QListView, one need to implement required Model interface functions (i guess atleast 5 Calls need to be implemented), and then a Delegate
Refer for delegate: http://doc.qt.nokia.com/4.7-snapshot/model-view-programming.html#a-simple-delegate

For using QListWidget, this interface is already implemted and you can create custom widgets by sub-classing QListWidgetItem, and just design your widget, no need to worry about ModelIndex, Delegate etc as in case of QListView
Refer: http://doc.qt.nokia.com/4.7-snapshot/qlistwidget.html#details

class MyListWidgetItem : public QListWidgetItem()
{

};

QListWidgetItem *newItem = new MyListWidgetItem;
newItem->setText(itemText);
listWidget->insertItem(row, newItem);

You also need to use QListWidget::setItemWidget()

Spooky
10th May 2011, 21:41
For using QListView, one need to implement required Model interface functions (i guess atleast 5 Calls need to be implemented), and then a Delegate
Refer for delegate: http://doc.qt.nokia.com/4.7-snapshot/model-view-programming.html#a-simple-delegate

For using QListWidget, this interface is already implemted and you can create custom widgets by sub-classing QListWidgetItem, and just design your widget, no need to worry about ModelIndex, Delegate etc as in case of QListView
Refer: http://doc.qt.nokia.com/4.7-snapshot/qlistwidget.html#details

class MyListWidgetItem : public QListWidgetItem()
{

};

QListWidgetItem *newItem = new MyListWidgetItem;
newItem->setText(itemText);
listWidget->insertItem(row, newItem);

You also need to use QListWidget::setItemWidget()Yes, but are you sure I can subclass QListWidgetItem to make list widget items that consist of regular QWidgets, like a QLabel and a QPushButton for example? QListWidgetItem does not seem to have any virtual function that I could implement to achieve this. And the only thing the documentation mentions about subclassing QListWidgetItems is the UserType.

Santosh Reddy
12th May 2011, 17:40
Ok, This is how you do it,

Sub-class QListWidgetItem to somthing like MyListWidgetItem, then in MyListWidgetItem ctor, you need to create custom QWidget, and whatever you want in it, like QLayout, QPushbutton, anything which you can put onto a QWidget.

Then use this new QWidget, and using QListWidget::setItemWidget(QWdiget*) , set it to the cell on which the newly created MyListWidgetItem is being created.

Example: the ctor looks somting like

class MyListWidgetItem : public QTableWidgetItem
{
public:
MyListWidgetItem(const QString &text, int type) ;
void setCustomWidget(void);
}

MyListWidgetItem::MyListWidgetItem(const QString &text, int type) : QTableWidgetItem(text, type)
{
;
}

MyListWidgetItem::setCustomWidget(void)
{
QWidget* customWdiget = new QWdiget();
customWdiget->setName(text);

// add more widgets onto customWdiget
// then add this widget to the table cell, where this MyListWidgetItem is present
this->tableWidget()->setCellWidget(this->row(), this->column(), customWdiget);
}

Good Luck...

Spooky
17th May 2011, 10:13
Hm, I made a simple test with a QListWidget like this:
class MyListWidgetItem : public QListWidgetItem
{
public:
MyListWidgetItem( const QString& text, QListWidget* parent = 0, int type = Type ) : QListWidgetItem( text, parent, type ) {}

void setCustomWidget()
{
QPushButton* button = new QPushButton( "Button" );
this->listWidget()->setItemWidget( this, button );
}
};




QListWidget lw;
lw.addItem( new MyListWidgetItem( "" ) );
lw.show();but it won't show the QPushButton. Also the documentation says
This function should only be used to display static content in the place of a list widget item. If you want to display custom dynamic content or implement a custom editor widget, use QListView and subclass QItemDelegate instead.So if I want to have clickable QPushButtons, I would still have to do it via QListView and QItemDelegate? (And handle the interaction manually there.)

Santosh Reddy
17th May 2011, 17:45
Yes, you can use it only for static content, I guess still you can connect signals to the widget, may not be able to edit it graphically

Here is an example of cutom widget with QPushButtons, with the screenshot attached, its bit tricky, the baseclass QListWidgetItem has to be already present/added in the QListWidget for setItemWidget() to work.

And again, you if you need to edit the widget, like enter some data, in text filed, you better use QDelegateItem, use QListView to be more generic. It would be your design decision.


6434




void MainWindow::AddCustomListWidgets(QListWidget* listWidget) const
{
listWidget->setAlternatingRowColors(true);

QListWidgetItem* new_item;

new_item = new QListWidgetItem(QString("Standard QListWidgetItem 1"), listWidget);
new_item = new QLWIPushButton(QString("QPushButtonItem 1"), listWidget);
listWidget->addItem(new QListWidgetItem(QString("Standard QListWidgetItem 2")));
new_item = new QLWIPushButton(QString("QPushButtonItem 2"), listWidget);
listWidget->addItem(new QListWidgetItem(QString("Standard QListWidgetItem 3")));
new_item = new QLWIPushButton(QString("QPushButtonItem 3"), listWidget);
listWidget->addItem(new QListWidgetItem(QString("Standard QListWidgetItem 4")));

}

QLWIPushButton::QLWIPushButton(const QString text, QListWidget* view)
: QListWidgetItem(view)
{
QWidget* widget = new QWidget;
QGridLayout* layout = new QGridLayout();

layout->addWidget(new QPushButton(text), 0, 0);
layout->addWidget(new QPushButton(text), 0, 1);
layout->addWidget(new QPushButton(text), 1, 0);
layout->addWidget(new QPushButton(text), 1, 1);

widget->setLayout(layout);

view->setItemWidget(this, widget);
setSizeHint(widget->sizeHint());
}