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

endRemoveRows() and QML ListView deleteLater() synchronization

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
deletelaterlistviewqml
2 Posts 2 Posters 868 Views
  • 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 10 Feb 2019, 18:52 last edited by Zaraka 2 Oct 2019, 20:22
    #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 4 Nov 2019, 08:32 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