How does MQL TreeView release its resource?
-
Hi:
I setup a subclass of QAbstractItemModel according to this link:
https://doc.qt.io/qt-5/qtwidgets-itemviews-simpletreemodel-example.htmlIn 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 -
@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 ;-)
-
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 objectline 43 is in the delegate and like this:
text: "" + styleData.value.itemTextdeleteLater() 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 -
@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.
-
@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