我正在学习QML以及QML和C ++代码之间的通信。 在此示例中,QML和C ++中的视图应通过一个通用模型进行同步。我已将模型导出到QML。 QML还显示正确的项目数。 不幸的是,在这个例子中,C ++和QML之间的checked属性不同步(实际上没有其他属性)。而连接到同一模型的C ++代码中的两个视图是同步的。
缺少什么?或者这是正常的行为,因为同步只是一种方式吗?
main.cpp中:
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QStandardItemModel>
#include <QStandardItem>
#include <QQmlContext>
#include <QHash>
#include <QListView>
class CppModel :public QStandardItemModel{
QHash<int, QByteArray> _roleNames;
public:
CppModel(QObject *p=0):QStandardItemModel(p)
{
_roleNames[Qt::DisplayRole] = "name";
_roleNames[Qt::CheckStateRole] = "checked";
}
QHash<int, QByteArray> roleNames() const
{
return _roleNames;
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
CppModel m;
QStandardItem *it = new QStandardItem();
it->setCheckable(true);
it->setData("S1",Qt::DisplayRole);
m.appendRow(it);
it = new QStandardItem();
it->setCheckable(true);
it->setData("S2",Qt::DisplayRole);
m.appendRow(it);
it = new QStandardItem();
it->setCheckable(true);
it->setData("S3",Qt::DisplayRole);
m.appendRow(it);
QListView *v1 = new QListView(0);
v1->setModel(&m);
v1->show();
QListView *v2 = new QListView(0);
v2->setModel(&m);
v2->show();
QQmlApplicationEngine engine;
QQmlContext *ctxt = engine.rootContext();
ctxt->setContextProperty("cppmodel", &m);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml:
import QtQuick 2.6
import QtQuick.Controls 1.5
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Model Test")
ListModel {
// id :cppmodel // *(1)* If this line active, this QML model will shadow C++ model with same name and
// QML views will be synchron.
// However, C++ views won't be updated
// If this line is disabled, Checking items in C++ models will update QML items
// but QML views don't react on mouse-clicks. Obviouly, set method dowsn't work with C++ models
ListElement { name: "S1"; checked:0; }
ListElement { name: "S2"; checked:0; }
ListElement { name: "S3"; checked:0; }
}
Component {
id: myDelegate
Rectangle {
color: "green" //ListView.isCurrentItem ? "black" : "red"
width: 200
height: 50
Rectangle {
color: checked ? "red" : "blue"
width: 20
height: 20
x: 10
y: 10
MouseArea {
anchors.fill: parent
onClicked: {
cppmodel.set(index, {"checked":checked?0:1} ) //*(2)* This works with QML models but not with C++
}
}
}
Text{
x:40
y: 10
text: name
}
}
}
ListView {
id: lv1
width:220
height: 400
x: 0
clip: true
model: cppmodel
delegate: myDelegate
focus: true
}
ListView {
id: lv2
width:220
height: 400
x: 250
clip: true
model: cppmodel
delegate: myDelegate
focus: true
}
}
编辑:更新了代码。在评论中添加了说明