Qt / Qml在ListView中管理动态C ++项

时间:2017-03-09 10:49:36

标签: c++ qt listview qml

我构建了一个C ++ / QML应用程序,其中我在QML ListView中使用基于QList的模型。我已经从Qt的示例中调整了它(http://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html),所以我将使用他们的代码来解决我的问题。

假设我已将其示例代码改编为以下内容:

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添加了一个带有调试消息的析构函数,以便我可以验证是否正在释放旧对象。但他们不是!因此,我不是在_dataList调用之前手动浏览clear(),而是仅管理std::shared_ptr<QObject*>的列表,以便代码最终看起来像:

public:
    void loadNewData()
    {
        QList<Object*> modelList;
        _dataList.clear();

        auto temp = std::make_shared<DataObject>("Item 1", "red");
        _dataList.push_back(temp);
        modelList.push_pack(temp.get()); 

        ...

        rootContext()->setContextProperty("myModel", QVariant::fromValue(modelList));
    }

private:
    QList<std::shared_ptr<QObject>> _dataList;

现在这种方式奏效了。我确实在我的DataObject析构函数中看到了断点/调试消息(我之前没有看到过),但这导致了一个新问题。我会在rootContext->setContextProperty() QListViewPrivate::releaseItem()中遇到崩溃(我认为这就是它的名称),这让我相信它正在尝试释放{{1}中已经清除的对象}。但如果是这样的话,为什么_dataList.clear()的析构函数被调用了呢?

我现在的解决方案是在DataObject之前致电rootContext()->setContextProperty("myModel", QVariant{});。像这样:

_dataList.clear

但这感觉就像是黑客。

管理这些动态对象的“更好”方法是什么(我实际上发现这是Qt中最模糊的方面之一)?我可以将它们附加到一个父对象上,该对象在每次调用void loadNewData() { QList<Object*> modelList; rootContext()->setContextProperty("myModel", QVariant{}); _dataList.clear(); ... 时都会被重置,但是为了这个目的而存在一个对象似乎也不正确。

另一个问题是,当我尝试直接使用loadNewData对象时:

_dataList

在将它声明为元类型(因此rootContext()->setContextProperty("myModel", QVariant::fromValue(_dataList));)后,我无法完成这项工作,QML从未按预期呈现对象。但也许这完全值得另一个问题。

0 个答案:

没有答案