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

故事扮演 提交于 2019-12-20 03:10:10

问题


There is a model inherited from QAbstractListModel, I use it in qml. One of the properties of this model are parameters, they are specific to the element type of this model. That is one element the parameters of this class TemperatureParam, DifrentParamType another, a third still something... How can I pass an object to qml and to be sure that the memory is freed after use? The code below now works as I need to, but it seems to me that it's not safe.

Param class is so trivial:

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

Model class (Here's what I'm asking):

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 something like this:

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()
    }
}

回答1:


According to the 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.

Generally an application doesn't need to set an object's ownership explicitly. As you can read here, by default, an object that is created by QML has JavaScriptOwnership.

Objects returned from C++ method calls will be set to JavaScriptOwnership also but this applies only to explicit invocations of Q_INVOKABLE methods or slots.

Because the method data is not an explicit C++ method call, you should consider to set the object ownership to QQmlEngine::JavaScriptOwnership calling setObjectOwnership()

So, in general:

  • Don't use QQmlEngine::CppOwnership if you want QML to destroy the object. The associated data will be deleted when appropriate (i.e. after the garbage collector has discovered that there are no more live references to the value)
  • A QSharedPointer probably wouldn't work. You have more information here.


来源:https://stackoverflow.com/questions/36491263/send-object-from-c-to-qml-what-about-free-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!