Qt5.6 QML, ¿por qué se destruyen los modelos dinámicos después de la recolección de basura?
Tengo un número variable de componentes, así que estoy tratando de dar a cada uno su propiomodel
. En este ejemplo, acabo de crear uno, pero la idea es la misma.
GC () es un poco aleatorio, así que en el ejemplo, ifuerza el gc () después de un clic para eliminar el problema. Lo que pasa es que elmodel
se destruye y se vuelve nulo. después de eso, el método de clic no puede usarlo.
main.qml:
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.2
import com.example.qml 1.0
ApplicationWindow
{
visible: true
width: 640
height: 480
// builder of dynamic models
ModelFactory { id: maker }
Column
{
anchors.fill: parent
Repeater
{
// create dynamic model
model: maker.makeModel();
delegate: Label
{
id: label
text: model.name
MouseArea
{
anchors.fill: parent
onClicked:
{
// works once until gc()
console.log("clicked on " + model.name)
// wont work anymore. model is destroyed
gc();
}
}
}
}
}
}
c ++ / mymodel.h:
#include <QAbstractListModel>
#include <QQmlApplicationEngine>
#include <QObject>
#include <QString>
#include <QDebug>
class BoxModel : public QAbstractListModel
{
Q_OBJECT
public:
~BoxModel()
{
// see that it does get destroyed
qDebug() << "~BoxModel()";
}
int rowCount(const QModelIndex& parent = QModelIndex()) const override
{
return 5;
}
QVariant data(const QModelIndex &index, int role) const override
{
int ix = index.row();
if (ix < 1) return "Larry";
if (ix < 2) return "Barry";
if (ix < 3) return "Gary";
if (ix < 4) return "Harry";
return "Sally";
}
QHash<int, QByteArray> roleNames() const override
{
QHash<int, QByteArray> roles;
roles[Qt::UserRole+1] = "name";
return roles;
}
};
class ModelFactory: public QObject
{
Q_OBJECT
public:
Q_INVOKABLE BoxModel* makeModel()
{
return new BoxModel();
}
};
main.cpp solo registra los tipos:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <qqmlcontext.h>
#include <qqml.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include "mymodel.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<BoxModel>("com.example.qml", 1, 0, "BoxModel");
qmlRegisterType<ModelFactory>("com.example.qml", 1, 0, "ModelFactory");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
lo que ves
Haga clic en cualquiera de los nombres. funcionará una vez y después de eso estarán indefinidos porquemodel
se vuelve nulo.
p.ej
qml: clicked on Sally
~BoxModel()
qml: clicked on undefined
Mi pregunta espor qué ¿Es esto cuando todavía tengo una referencia?
En el ejemplo,onClicked
podría cambiarse alabel.text
más bien quemodel.name
arreglar, pero elreal el problema es que, en general, elmodel
el objeto accede a él en cualquier momento, para cualquier dato. Por ejemplo, cuando el cuadro necesita volver a dibujarse. aleatoriamente los datos se han ido, dependiendo de GC.
He intentado hacer que c ++ administre la vida del modelo dinámico. esto podría funcionar si lo sécuando exactamente QML ha terminado con eso.
Gracias por información e ideas.
ejecutándose en Windows 8.1 / qt5.6mingw
EDIT1: archivos como una esencia,https://gist.github.com/anonymous/86118b67ec804e6149423c14792f312d