c++ - 将对象从 C++ 发送到 qml。空闲内存呢?

标签 c++ qt memory-leaks qml

有一个模型继承自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()
    }
}

最佳答案

根据documentation :

When data is transferred from C++ to QML, the ownership of the data always remains with C++. The exception to this rule is when a QObject is returned from an explicit C++ method call: in this case, the QML engine assumes ownership of the object, unless the ownership of the object has explicitly been set to remain with C++ by invoking QQmlEngine::setObjectOwnership() with QQmlEngine::CppOwnership specified.

通常,应用程序不需要显式设置对象的所有权。如您所见here ,默认情况下,由 QML 创建的对象具有 JavaScriptOwnership

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

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

所以,一般来说:

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

关于c++ - 将对象从 C++ 发送到 qml。空闲内存呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36491263/

相关文章:

multithreading - 在等待通知std::condition_variable的过程中执行 “wait callback”

IOSurface 在 iOS 12 及以上版本逐渐增加内存

c++ - Winapi ListView_GetItemText 错误的输出格式

c++ - 调用重写的虚函数而不是重载

android - qt qml : deploying sqlite database to android using . qrc 文件不工作

javascript - 为什么对象在被 document.getElementById 编辑后必须为 IE 清空?

java - 使用 setText 时内存泄漏

c++ - 为什么基于范围的 for 循环中的结构化绑定(bind)只是拷贝而不是引用?

c++ - 实现与头文件

c++ - 使用 vbo ,使用着色器绘制纹理,但不显示任何内容