我有一个QObjects列表,用作ListView的qml模型。我可以更改其属性,但不能调用任何插槽或Q_INVOKABLE方法。这是我的问题的最小示例(可惜它仍然很大)。
使用属性和可调用方法定义一个非常简单的类
// DummyObject.h
class DummyElem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString dummy READ getDummy CONSTANT)
public:
explicit DummyElem(QObject *parent = nullptr);
QString getDummy();
Q_INVOKABLE void notifyStuff();
};
实现这个简单类的简单方法
// DummyObject.cpp
#include "DummyElem.h"
#include <QDebug>
DummyElem::DummyElem(QObject *parent) : QObject(parent) {}
QString DummyElem::getDummy() {return "lorem";}
void DummyElem::notifyStuff() {qDebug() << "ipsum";}
使用列表作为根属性启动qml应用程序。完全是从教程中复制粘贴的,他们在其中将其称为q_incokable方法。
// main.cpp
#include "DummyElem.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QList<QObject*> dataList;
dataList.append(new DummyElem);
dataList.append(new DummyElem);
QQmlApplicationEngine engine;
QQmlContext* context = engine.rootContext();
context->setContextProperty("dataModel", QVariant::fromValue(dataList));
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
用ListView和一个委托描述一个qml布局,单击该委托将调用c ++方法。
// main.qml
import QtQuick 2.7
import QtQuick.Window 2.2
Window {
visible: true
ListView {
anchors.fill: parent
model: dataModel
delegate: Component {
Text {
text: model.dummy
MouseArea {
anchors.fill: parent
onClicked: {model.notifyStuff()}
}
}
}
}
}
这个问题很难调试,因为C ++类模型无法json-strigified,也无法获取其javascript entry()。我得到的错误是“未定义不是函数”,这也是很酷的。
我尝试在QML中注册Qt类型,但这也没有执行任何操作。
我使用的是Qt库版本5.9.4,但是QtCreator中的“所需的最低qt版本”框设置为“ Qt 5.6”。
答案 0 :(得分:2)
您需要使用modelData
。我不确定原因为何,最可能是因为QVariantList
。您可以在this page上阅读更多内容。
Window {
visible: true
ListView {
anchors.fill: parent
model: dataModel
delegate: Component {
Text {
text: modelData.dummy
MouseArea {
anchors.fill: parent
onClicked: modelData.notifyStuff();
}
}
}
}
}
有趣的事实:这是我在Qt 5.11.3上遇到的错误:
TypeError: Property 'notifyStuff' of object QQmlDMObjectData(0x5585fe567650) is not a function
至少比undefined
更具说服力,但我仍不能完全描述。