Search code examples
c++qtc++11qt5

How detach my custom widget from Qt QWidgetList?


I have a container std::map<std::string, unique_ptr<ItemWidget>> widgets that contains pointers to my widgets, so all of my widgets exist separately and independend from QListWidget object. Sometimes i need to hide some of widgets temporarily, sometimes to delete ones finally. So my code implements this:

ui->listWidget->clear()
for (auto it : widgets) {
    auto item = new QListWidgetItem();
    item->setSizeHint(it->size());
    ui->listWidget->addItem(item);
    ui->listWidget->setItemWidget(item, it);
}

Now i read that ui->listWidget->clear() calls delete for all list's items. And thats why my list has all items with no data.

I want to list to delete my widgets from itself, but without any impact to my widgets. Can i?

UDPATE. This is not about clear. Function that deletes my CustomWidget is probably setItemWidget. I am not so sure, but problem is definitly that some class, function or else deletes my ItemWidget


Solution

  • Why you even guard QWidget by unique_ptr? They aren't meant to. They are stored in global repository, registered in event queue , are owned by parent widgets.

    You can't even safely delete widget from inside of running event loop. You have to use QObject::deleteLater() instead of delete on them or you have a case of UB.

    unique_ptr is not copyable so code above really claims to cause disaster. And QListWidget is Qt-friendly analog of " container of smart unowning pointers".

    Qt got "weak pointer class" for QObjects. It's QPointer. It clears itself if it pointed at QObject instance and that got deleted from framework.

    So, it sounds like you need to use QList<QWidget*> or QList<QPointer<QWidget*>> in your case. And QMap. And it got own owning smart pointer QSharedPointer. And no C++ smart pointers, framework is not designed to be used with them or you have be careful with deleters.