问题
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