Qt5.6 QML, warum werden dynamische Modelle nach der Garbage Collection zerstört?
Ich habe eine variable Anzahl von Komponenten, also versuche ich, jeder eine eigenemodel
. In diesem Beispiel erstelle ich nur eine, aber die Idee ist dieselbe.
GC () ist ein bisschen zufällig, also in dem Beispiel, ichMach the gc () nach einem Klick, um das Problem zu beseitigen. Was passiert ist, dass dasmodel
wird zerstört und wird null. danach kann die click-Methode sie nicht mehr verwenden.
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 registriert nur die Typen:
#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();
}
was Sie sehen
Klicken Sie auf einen der Namen. es wird einmal funktionieren und danach werden sie undefiniert sein, weilmodel
wird zu null.
z.
qml: clicked on Sally
~BoxModel()
qml: clicked on undefined
Meine Frage istWaru Ist das, wenn ich noch einen Verweis darauf habe?
Im BeispielonClicked
könnte in @ geändert werdlabel.text
eher, alsmodel.name
zu beheben, aber dieech Problem ist, dass im Allgemeinen diemodel
uf @ kann das Objekt jederzeit für beliebige Daten zugreifen. Zum Beispiel, wenn die Box neu gezeichnet werden muss. Je nach GC gehen die Daten nach dem Zufallsprinzip verloren.
Ich habe versucht, c ++ dazu zu bringen, das Leben des dynamischen Modells zu verwalten. Das könnte funktionieren, wenn ich @ wewan Genau damit ist QML fertig.
Danke für Infos und Ideen.
running unter Windows 8.1 / qt5.6mingw
EDIT1: Dateien als Zusammenfassung,https: //gist.github.com/anonymous/86118b67ec804e6149423c14792f312