C++ Qt/Qml管理动态C++;列表视图中的项目
我已经构建了一个C++/QML应用程序,其中我在QML列表视图中使用了基于QList的模型。我从Qt的示例()中改编了它,所以我将使用它们的代码来回答我的问题 假设我已将其示例代码改编为以下内容:C++ Qt/Qml管理动态C++;列表视图中的项目,c++,qt,listview,qml,C++,Qt,Listview,Qml,我已经构建了一个C++/QML应用程序,其中我在QML列表视图中使用了基于QList的模型。我从Qt的示例()中改编了它,所以我将使用它们的代码来回答我的问题 假设我已将其示例代码改编为以下内容: class MyDataWidget : public QQuickWidget { public: MyDataWidget(QObject* parent = nullptr) : QQuickWidget(parent) { setSource(
class MyDataWidget : public QQuickWidget
{
public:
MyDataWidget(QObject* parent = nullptr)
: QQuickWidget(parent)
{
setSource(QUrl("qrc:/qml/myDataWidget.qml"));
}
void loadNewData()
{
_dataList.clear();
_dataList.append(new DataObject("Item 1", "red"));
_dataList.append(new DataObject("Item 2", "green"));
_dataList.append(new DataObject("Item 3", "blue"));
_dataList.append(new DataObject("Item 4", "yellow"));
rootContext()->setContextProperty("myModel", QVariant::fromValue(_dataList));
}
private:
QList<QObject*> _dataList;
}
现在这种方法奏效了。我确实在我的DataObject析构函数中看到了断点/调试消息(我以前没有看到),但这导致了一个新问题。我会在QListViewPrivate::releaseItem()
中的rootContext->setContextProperty()
中发生崩溃(我想这就是它的名字),这让我相信它试图释放在\u dataList.clear()中已清除的对象。但是如果是这样的话,为什么要调用数据对象的析构函数呢
目前,我的解决方案是调用rootContext()->setContextProperty(“myModel”,QVariant{})在\u数据列表之前添加code>。清除。例如:
void loadNewData()
{
QList<Object*> modelList;
rootContext()->setContextProperty("myModel", QVariant{});
_dataList.clear();
...
void loadNewData()
{
QList模型列表;
rootContext()->setContextProperty(“myModel”,QVariant{});
_dataList.clear();
...
但这感觉像是一个黑客
管理这些动态对象的“更好”方法是什么(实际上,我发现这是Qt最模糊的方面之一)?我可以将它们附加到父对象上,在每次调用loadNewData
时重置,但是让一个对象单独存在似乎也不正确
另一个问题是,当我试图直接像这样使用\u dataList
对象时:
rootContext()->setContextProperty(“myModel”,QVariant::fromValue(_dataList));
在将其声明为元类型(因此Q\u DECLARE\u METATYPE
)之后,我始终无法完成这项工作,QML从未按预期呈现对象。但这可能需要另外一个问题。首先,如果您有一些指针的QList
,请使用list.clear()从该列表中删除项
或显然不会删除对象本身。您必须自己管理内存,并在调用clear()
时删除它们,例如,在您清除列表之前使用qDeleteAll(list);
。我不知道qDeleteAll(list)
。我会试试看。我喜欢一个简单的调用,而不是自己用共享指针(或其他东西)来管理内存。qdeletall(list);
实际上只是一个删除容器中所有项目的循环,没什么特别的,但由于有时需要它,它会让代码更清晰:调用qdeletall(list)
仍然需要调用rootContext()->setContextProperty(“myModel”,QVariant{})
事先。有没有办法在不临时设置空列表的情况下清理已分配的对象?我认为问题更多的是,当您通过QList的方法修改它时,QList是一个非托管列表。QML如何知道模型已更改,QList没有数据更改信号。您的方法最好使用只读列表。如果您需要动态列表,更好的方法是使用适当的列表模型,例如,并将其公开给QML。(我认为上面的模型数据链接中也提到了这一点)首先,如果您有一些指针的QList
,则使用list.clear()
从该列表中删除项目,否则显然不会删除对象本身。你必须自己管理内存,并在调用clear()
时删除它们,例如,在清除列表之前使用qDeleteAll(list);
。我不知道qDeleteAll(list)
。我会试试。我喜欢一个简单的调用,而不是自己用共享指针(或其他东西)管理内存.qdeletall(list);
实际上只是一个删除容器中所有项的循环,没有什么特别之处,但由于有时需要它,它使代码更清晰:调用qdeletall(list)
仍然需要调用rootContext()->setContextProperty(“myModel”,QVariant{})
事先。有没有办法在不临时设置空列表的情况下清理已分配的对象?我认为问题更多的是,当您通过QList的方法修改它时,QList是一个非托管列表。QML如何知道模型已更改,QList没有数据更改信号。您的方法最好使用只读如果您需要一个动态列表,更好的方法是使用一个合适的列表模型,比如,并将其公开给QML。(我想上面的模型数据链接中也提到了这一点)
void loadNewData()
{
QList<Object*> modelList;
rootContext()->setContextProperty("myModel", QVariant{});
_dataList.clear();
...