Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. endRemoveRows() and QML ListView deleteLater() synchronization
Forum Updated to NodeBB v4.3 + New Features

endRemoveRows() and QML ListView deleteLater() synchronization

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
deletelaterlistviewqml
2 Posts 2 Posters 890 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    Zaraka
    wrote on last edited by Zaraka
    #1

    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()?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SO_CubicF
      wrote on last edited by
      #2

      Had the same problem.

      Fixed it by not binding the object referenced by the role to a property and using the property but using the role name directly to acces the model item.

      Instead of

      property MyItem myItem: model.object
      text: myItem.foo
      

      try

      text: model.object.foo
      
      1 Reply Last reply
      1

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved