endRemoveRows() and QML ListView deleteLater() synchronization



  • Hello,
    I've stumbled on curious problem. If I deleteLater() object after caling endRemoveRows(). ListView delegates will not get destroyed in time and every binding to the deleted item will results in a lot of TypeError: Cannot read property 'foo' of null

    Here's an example:
    Let's preted that I have defined C++ Item

    class MyItem : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString foo READ foo WRITE setFoo NOTIFY fooChanged)
    ...
    }
    

    And I put these items into a QAbstractListModel

    class MyModel : public QAbstractListModel {
        Q_OBJECT
    public:
    QHash<int, QByteArray> Model::roleNames() const {
        QHash<int, QByteArray> roles;
        roles[Qt::UserRole] = "object";
        return roles;
    }
    ...
    }
    

    where data() with ObjectRole returns *Item
    and I remove these Items like this

    MyModel::removeItem(MyÏtem* item) {
        if (item && m_items.contains(item)) {
            int index = m_items.indexOf(item);
            beginRemoveRows(QModelIndex(), index, index);
            m_items.removeAt(index);
            endRemoveRows();
            item->deleteLater();
        }
    

    Finally my QML for this model can be simple as this

    ListView {
        delegate: Text {
            property MyItem myItem: model.object
            text: myItem.foo
        }
    }
    

    After removing item from model, Qt will fire that TypeError. but item will be destroyed both from C++ and from QML. But if I stall deleteLater like this QTimer::singleShot(10, [=]{ item->deleteLater();}); then everything will works okay. Also I have to use this nesting because my Items are quite big and I connect their signals and pass their pointer to a lot of places. I also have to delete object, because the item holds a lot of memory that I need to be freed.
    It's obvious the C++ deletes object much faster than QML destroys ListView delegate. The question is, how can my C++ Model know when it is safe to deleteLater()?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.