将对象从c++发送到qml.空闲内存怎么样

Send object from c++ to qml. What about free memory?

本文关键字:qml 内存 怎么样 对象 c++      更新时间:2023-10-16

有一个从QAbstractListModel继承的模型,我在qml中使用它。此模型的属性之一是参数,它们特定于此模型的图元类型。这是一个元素,这个类的参数TemperatureParam,DifrentParamType,另一个,第三个仍然是。。。如何将对象传递给qml并确保在使用后释放内存?下面的代码现在可以根据我的需要工作,但在我看来它不安全。

Param类是如此琐碎:

class QuickTemperatureParam : public QObject
{
    Q_OBJECT
    Q_PROPERTY(float param1 READ param1 WRITE setParam1)
//...
};

模型类(这是我要问的):

class SectionsModel : public QAbstractListModel
{
//...
QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override
{
//...
    int type = getType( idx );
    if (type == 1)
    {
        auto p = new QuickTemperatureParam( idx );
        p->deleteLater(); // This is all right or no?
        return qVariantFromValue(p);
    }
    else if (type == 2)
    //...
}
};

QML是这样的:

ListView {
    model: sectionsModel
    delegate: Rectangle {
        color: model.statusColor
        ItemDelegate {
            text: model.title
            highlighted: ListView.isCurrentItem
            onPressed:
                switch ( model.type )
                {
                case SectionType.Temperature:
                    temperatureParam.openItem(model)
                    break;
                case SectionType.Lighting:
                    lightingParam.open(model)
                    break;
                }
        }
    }
}
Popup {
    id: temperatureParam
    function openItem(model)
    {
        var p = model.param
        params.itemAt(0).range.from = params.itemAt(1).range.from = p.min
        params.itemAt(0).range.to = params.itemAt(1).range.to = p.max
        params.itemAt(0).range.setValues( p.dayMin, p.dayMax )
        params.itemAt(1).range.setValues( p.nightMin, p.nightMax )
        open()
    }
}

根据文档:

当数据从C++传输到QML时,数据的所有权始终使用C++。当QObject从显式C++方法调用返回:在这种情况下,QML引擎假定对象的所有权,除非通过调用,对象已明确设置为保留在C++中QQmlEngine::setObjectOwnership()与QQmlEngine::CppOwnership指定。

通常,应用程序不需要显式地设置对象的所有权。正如您在这里看到的,默认情况下,QML创建的对象具有JavaScriptOwnership

从C++方法调用返回的对象也将设置为JavaScriptOwnership,但这仅适用于Q_INVOKABLE方法或槽的显式调用。

因为方法data不是显式C++方法调用,所以应该考虑将对象所有权设置为调用setObjectOwnership()QQmlEngine::JavaScriptOwnership

所以,总的来说:

  • 如果希望QML销毁对象,请不要使用QQmlEngine::CppOwnership。相关联的数据将在适当的时候被删除(即,在垃圾收集器发现不再有对该值的实时引用之后)
  • QSharedPointer可能不起作用。您在这里有更多信息