Search code examples
c++qtqtguiqlistwidgetqlistwidgetitem

Items in a QListWidget turn invisible after reordering


I have a QListWidget which is populated by custom widgets with the use of setItemWidget.

These custom list items are completely static, they just have a bunch of labels with various texts and images. My QListWidget is displayed correctly. I allow drag-and-drop reordering, and after I move an item to a different position, it becomes invisible. It does not vanish, because it takes up space in the display, I can even click on it, it's just completely invisible, as if all the labels inside it suddenly became blank. Interestingly, if I set a background color for these widgets, the custom background color is not cleared, only the contents.

If I insert generic QListWidgetItems into the QListQidget, they remain visible even after movement.

What causes the custom widgets to become blank, and how can I stop this from happening?

Example.

QListWidgetItem *item;
MyCustomWidget *custom;

item = new QListWidgetItem();
item->setText("This will remain visible");
listWidget->addItem(item);

item = new QListWidgetItem();
custom = new MyCustomWidget ();
custom->setName(QString("This will vanish")); // this will add text to one of the labels inside it.
listWidget->addItem(item);
item->setSizeHint(QSize(50,65));
listWidget->setItemWidget(item, custom);

After moving items around with the mouse, the items added via "normal" QListWidgetItems retain their contents, while those which were added via setItemWidget have their contents vanish.

Edit

Even if my custom widget is just a QLabel, its contents are gone after moving it.

QLabel *label;
item = new QListWidgetItem();
label = new QLabel();
label->setText("This label will vanish");
listWidget->addItem(item);
listWidget->setItemWidget(item, label);

As with the custom widget, its size and background color, if set, remain the same, so the item is not deleted. Only the contents of the label are cleared. If I set a background for the label itself (via setStyleSheet), it's cleared. If I set a background for the item itself, it remains.

Edit 2

It seems the Widget set in setItemWidget will be decoupled after a movement.

I created a button, which displays qDebug() << listWidget->itemWidget(listWidget->item(0)); when pressed. If I have custom widgets, or for simplicity's sake, QLabels as my items, before moving them around it displays QLabel(0x8b41fd8), after the movement it displays QObject(0x0). It seems the widget attached to the item is deleted.

The manual for setItemWidget states that "This function should only be used to display static content in the place of a list widget item." I thought it meant we shouldn't put pushable buttons, dynamically changing widgets etc. in them, but now it seems that "static content" means that the whole QListWidget itself must remain static?


Solution

  • in them, but now it seems that "static content" means that the whole QListWidget itself must remain static?

    Yes, continue reading the next sentence. That will make it clear what you need for all this.t

    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.