У меня есть переменное количество компонентов, поэтому я пытаюсь дать каждому свой собственный model
. В этом примере я просто создаю один, но идея та же.
GC() немного случайный, поэтому в примере я форсирую gc() после щелчка, чтобы устранить проблему. Что происходит, так это то, что model
уничтожается и становится нулевым. после этого метод click не может его использовать.
основной.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();
}
}
}
}
}
}
С++/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 просто регистрирует типы:
#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();
}
что ты видишь:
Нажмите на любое из имен. это сработает один раз, и после этого они будут неопределенными, потому что model
становится нулевым.
eg
qml: clicked on Sally
~BoxModel()
qml: clicked on undefined
Мой вопрос: почему это, когда у меня все еще есть ссылка на это?
В примере onClicked
можно изменить на label.text
, а не model.name
для исправления, но настоящая проблема заключается в том, что, как правило, model
доступен объекту в любое время для любых данных. Например, когда коробку нужно перерисовать. случайно данные исчезли, в зависимости от GC.
Я пытался заставить С++ управлять жизнью динамической модели. это могло бы сработать, если бы я знал, когда точно QML покончил с этим.
спасибо за информацию и идеи.
работает на windows 8.1/qt5.6mingw
EDIT1: файлы как суть, https://gist.github.com/anonymous/86118b67ec804e6149423c14792f312d
model: new BoxModel()
? - person Kuba hasn't forgotten Monica   schedule 19.05.2016model: maker.makeModel()
наmodel: BoxModel {}
, это сработает. я собираюсь посмотреть, решит ли это мою проблему, когда у меня будет несколько таких ящиков. Благодарю. - person jkj yuio   schedule 19.05.2016BoxModel
мог существовать сам по себе, чтобы ни одна фабрика не знала об этом. У меня была проблема в том, что мне нужно было отслеживать их внутри. должно было быть сделано с синглтоном, но это может работать таким образом. однако было бы хорошо, чтобы динамическая версия тоже работала. Благодарю. - person jkj yuio   schedule 19.05.2016