问题出在
initializeView
,model是该范围内的一个局部变量,当函数完成执行时,将从内存中删除每个局部变量。在第一种情况下,模型将在应用程序关闭时消除,在第二种情况下,模型将在
初始化视图
在显示窗口时,有两种可能的解决方案:
-
创建指针并管理传递到的内存
MainView
作为家长,以便他将其从内存中删除(最后一个是
QObject
s) :
void MainView::initializeView()
{
MyModel *model = new MyModel(this);
m_engine.rootContext()->setContextProperty("myModel", model);
m_engine.load(QUrl(QStringLiteral("qrc:/resources/qmls/main_test.qml")));
}
*。h类
#ifndef MAINVIEW_H
#define MAINVIEW_H
#include <QObject>
#include <QQmlApplicationEngine>
class MainView: public QObject
{
Q_OBJECT
public:
explicit MainView(QObject *parent=nullptr);
void initializeView();
private:
QQmlApplicationEngine m_engine;
MyModel model{this};
};
#endif
*。cpp公司
...
void MainView::initializeView()
{
m_engine.rootContext()->setContextProperty("myModel", &model);
m_engine.load(QUrl(QStringLiteral("qrc:/resources/qmls/main_test.qml")));
}
为了理解这种行为,我添加了更多的印象点:
MyModel::~MyModel()
{
qDebug()<<"destructor";
}
TableView {
...
Component.onCompleted: {
console.log("completed table")
if(!timer.running)
timer.running = true
}
}
ListView {
...
Component.onCompleted: {
console.log("completed list")
if(!timer.running)
timer.running = true
}
}
Timer {
id: timer
interval: 0;
onTriggered: console.log(myModel, table_view.model, list_view.model)
}
我得到以下信息:
MyModel
addAnimal
addAnimal
addAnimal
roleNames
data 0 0 257
data 0 0 258
data 1 0 257
data 1 0 258
data 2 0 257
data 2 0 258
roleNames
qml: completed list
data 0 0 257
data 0 0 258
qml: completed table
destructor
qml: null null null
我们注意到
ListView
管理加载数据,而
TableView
在负载的中间被称为析构函数。
可能的解释:我认为
列表视图
存储数据并制作副本,仅在模型通知时更新,也应在删除模型时通知以清理数据,这似乎是一个bug。另一方面
表格视图
,在加载和删除模型时为null,因此会通知它并清理数据。
进行另一项测试:
void MainView::initializeView()
{
MyModel *model = new MyModel;
m_engine.rootContext()->setContextProperty("myModel", model);
m_engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QTimer::singleShot(1000, model, &MyModel::deleteLater);
}
可以观察到,这两种方法都正确加载了数据,并且在第二秒钟后模型被销毁,但只收到通知的是
表格视图
因为它是唯一一个清理显示数据的程序,并且
列表视图
没有。
我的结论是
列表视图
缺陷