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. How does MQL TreeView release its resource?
QtWS25 Last Chance

How does MQL TreeView release its resource?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qml treeviewqabstractitemmobeginresetmodel
5 Posts 2 Posters 696 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.
  • K Offline
    K Offline
    kevinguo
    wrote on 22 Jul 2020, 18:27 last edited by
    #1

    Hi:

    I setup a subclass of QAbstractItemModel according to this link:
    https://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

    In my model class, I return a QVariant object from QAbstractItemModel's data() function. The value of the QVariant object is a pointer of an CTreeTypeString object and it has Q_PROPERTY. I create it by calling newTreeTypeString().

    // return the QVariant data
    QVariant CTreeModelDevice::newTreeTypeString(const QString &text)
    {
        CTreeTypeString *t = new CTreeTypeString(this);
        t->setText(text);
        QVariant v;
        v.setValue(t);
        return v;
    }
    
    // the class of treeview item
    class CTreeTypeString : public QObject
    {
        Q_OBJECT
    
        Q_PROPERTY(QString text READ getText WRITE setText NOTIFY textChanged)
    
        QString getText();
        void setText(QString text);
    
    signals:
        void textChanged();
    }
    
    qml:
        TreeView {
            model: CTreeModelDevice
            TableViewColumn {
                delegate: Text {
                               text: " " + styleData.value.text
                            }
            }
       }
    

    Upon a certain event, I refresh the treeview by:

    beginResetModel();
    setupModelData();
    endResetModel();
    

    setupModelData() calls newTreeTypeString() again to create new CTreeTypeString objects.

    All these work fine.

    Now it comes to the question: when and how CTreeTypeString objects are deleted?

    I notice that they are not deleted when I call beginResetModel() and endResetModel(). Instead, they are deleted when the main window is closed. Does this mean that QML framework holds the objects even they are not shown in the tree and only delete them when the treeview is destroyed.
    I also tried beginRemoveRows/endRemoveRows then beginInsertRows/endInsertRows. Same observation.

    Is this by design?
    Is there an "official" way in which I can explicitly delete the "unuseful" objects. I get QML errors if I delete them in setupModelData().

    Thanks
    Kevin

    S 1 Reply Last reply 22 Jul 2020, 19:34
    0
    • K kevinguo
      22 Jul 2020, 18:27

      Hi:

      I setup a subclass of QAbstractItemModel according to this link:
      https://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.html

      In my model class, I return a QVariant object from QAbstractItemModel's data() function. The value of the QVariant object is a pointer of an CTreeTypeString object and it has Q_PROPERTY. I create it by calling newTreeTypeString().

      // return the QVariant data
      QVariant CTreeModelDevice::newTreeTypeString(const QString &text)
      {
          CTreeTypeString *t = new CTreeTypeString(this);
          t->setText(text);
          QVariant v;
          v.setValue(t);
          return v;
      }
      
      // the class of treeview item
      class CTreeTypeString : public QObject
      {
          Q_OBJECT
      
          Q_PROPERTY(QString text READ getText WRITE setText NOTIFY textChanged)
      
          QString getText();
          void setText(QString text);
      
      signals:
          void textChanged();
      }
      
      qml:
          TreeView {
              model: CTreeModelDevice
              TableViewColumn {
                  delegate: Text {
                                 text: " " + styleData.value.text
                              }
              }
         }
      

      Upon a certain event, I refresh the treeview by:

      beginResetModel();
      setupModelData();
      endResetModel();
      

      setupModelData() calls newTreeTypeString() again to create new CTreeTypeString objects.

      All these work fine.

      Now it comes to the question: when and how CTreeTypeString objects are deleted?

      I notice that they are not deleted when I call beginResetModel() and endResetModel(). Instead, they are deleted when the main window is closed. Does this mean that QML framework holds the objects even they are not shown in the tree and only delete them when the treeview is destroyed.
      I also tried beginRemoveRows/endRemoveRows then beginInsertRows/endInsertRows. Same observation.

      Is this by design?
      Is there an "official" way in which I can explicitly delete the "unuseful" objects. I get QML errors if I delete them in setupModelData().

      Thanks
      Kevin

      S Offline
      S Offline
      sierdzio
      Moderators
      wrote on 22 Jul 2020, 19:34 last edited by
      #2

      @kevinguo said in How does MQL TreeView release its resource?:

      Now it comes to the question: when and how CTreeTypeString objects are deleted?
      I notice that they are not deleted when I call beginResetModel() and endResetModel(). Instead, they are deleted when the main window is closed. Does this mean that QML framework holds the objects even they are not shown in the tree and only delete them when the treeview is destroyed.
      I also tried beginRemoveRows/endRemoveRows then beginInsertRows/endInsertRows. Same observation.
      Is this by design?

      Yes. This is unrelated to QML. It does not hold on to your data there.

      CTreeTypeString *t = new CTreeTypeString(this);

      This C++ code is your culprit. You create a QObject and parent it to this (your model). So in order to delete it, you need to either:

      • delete the model
      • or delete the CTreeTypeString object(s) manually

      Is there an "official" way in which I can explicitly delete the "unuseful" objects. I get QML errors if I delete them in setupModelData().

      I think you should delete them after you finish your model reset. Best - call deleteLater() and Qt will handle it when event loop is ready.

      "official" way

      Just return a string... there is no need to use QObject here at all ;-)

      (Z(:^

      K 1 Reply Last reply 23 Jul 2020, 23:31
      1
      • S sierdzio
        22 Jul 2020, 19:34

        @kevinguo said in How does MQL TreeView release its resource?:

        Now it comes to the question: when and how CTreeTypeString objects are deleted?
        I notice that they are not deleted when I call beginResetModel() and endResetModel(). Instead, they are deleted when the main window is closed. Does this mean that QML framework holds the objects even they are not shown in the tree and only delete them when the treeview is destroyed.
        I also tried beginRemoveRows/endRemoveRows then beginInsertRows/endInsertRows. Same observation.
        Is this by design?

        Yes. This is unrelated to QML. It does not hold on to your data there.

        CTreeTypeString *t = new CTreeTypeString(this);

        This C++ code is your culprit. You create a QObject and parent it to this (your model). So in order to delete it, you need to either:

        • delete the model
        • or delete the CTreeTypeString object(s) manually

        Is there an "official" way in which I can explicitly delete the "unuseful" objects. I get QML errors if I delete them in setupModelData().

        I think you should delete them after you finish your model reset. Best - call deleteLater() and Qt will handle it when event loop is ready.

        "official" way

        Just return a string... there is no need to use QObject here at all ;-)

        K Offline
        K Offline
        kevinguo
        wrote on 23 Jul 2020, 23:31 last edited by
        #3

        @sierdzio

        Thanks for your response.

        It works if I manually delete the data after beginResetModel()/endResetModel() block.

        However, if I only refresh a certain branch by calling beginRemoveRows()/endRemoveRows() and beginInsertRows()/endInsertRows(), then delete the data after endInsertRows(), it causes this warning/error:
        xxx.qml:43 TypeError: Value is null and could not be converted to an object

        line 43 is in the delegate and like this:
        text: "" + styleData.value.itemText

        deleteLater() doesn't work for me too because I call this in event loop so the object will be deleted immediately in the same event.

        I have a workaround: store the data and delete it at the next refresh event.

        Thanks
        Kevin

        S 1 Reply Last reply 24 Jul 2020, 05:20
        0
        • K kevinguo
          23 Jul 2020, 23:31

          @sierdzio

          Thanks for your response.

          It works if I manually delete the data after beginResetModel()/endResetModel() block.

          However, if I only refresh a certain branch by calling beginRemoveRows()/endRemoveRows() and beginInsertRows()/endInsertRows(), then delete the data after endInsertRows(), it causes this warning/error:
          xxx.qml:43 TypeError: Value is null and could not be converted to an object

          line 43 is in the delegate and like this:
          text: "" + styleData.value.itemText

          deleteLater() doesn't work for me too because I call this in event loop so the object will be deleted immediately in the same event.

          I have a workaround: store the data and delete it at the next refresh event.

          Thanks
          Kevin

          S Offline
          S Offline
          sierdzio
          Moderators
          wrote on 24 Jul 2020, 05:20 last edited by
          #4

          @kevinguo said in How does MQL TreeView release its resource?:

          I have a workaround: store the data and delete it at the next refresh event.

          Or you can use a QSharedPointer so it will happen automatically.

          Another possibility - use Q_GADGET and store your objects on stack, not as pointers.

          (Z(:^

          K 1 Reply Last reply 28 Jul 2020, 18:20
          1
          • S sierdzio
            24 Jul 2020, 05:20

            @kevinguo said in How does MQL TreeView release its resource?:

            I have a workaround: store the data and delete it at the next refresh event.

            Or you can use a QSharedPointer so it will happen automatically.

            Another possibility - use Q_GADGET and store your objects on stack, not as pointers.

            K Offline
            K Offline
            kevinguo
            wrote on 28 Jul 2020, 18:20 last edited by
            #5

            @sierdzio said in How does MQL TreeView release its resource?:

            I have a workaround: store the data and delete it at the next refresh event.

            In order to have more control, my final choice is to delete it manually instead of using auto pointer.
            But anyways, thanks for your suggestion.
            Kevin

            1 Reply Last reply
            0

            2/5

            22 Jul 2020, 19:34

            • Login

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