c++ - 无法在 QML ListView 中调用 Qt c++ 方法
问题描述
我有一个 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 条目()。我得到的错误是“未定义不是函数”,这也很酷。我尝试在 QML 中注册 Qt 类型,但这也没有做任何事情。
我使用的是 Qt 库版本 5.9.4,但 QtCreator 中的“所需的最小 qt 版本”框设置为“Qt 5.6”。
解决方案
你需要使用modelData
. 我不完全确定为什么,很可能是因为QVariantList
. 您可以在此页面上阅读更多内容。
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
,但我想说的仍然不是完全描述性的。
推荐阅读
- spring - 自动装配按类型键入的所有接口
- angular - 如何在Angular中的另一个方法之后同步调用方法?
- jupyter-notebook - Jupyter 内核使用与 Conda 环境不同的 Python 版本
- node.js - MacOS 10.14.6 上的节点安装问题
- sql - SQL 更新问题条件除法
- php - Codeigniter Rest 库中不支持的协议
- r - R:将 xlsx 文档分成多个小标题
- php - 无法加载动态库'/usr/lib/php/20160303/pdo_mysql.so
- node.js - Node.js 和 Express.js 服务器的 Heroku 部署 404 错误
- c - 我的 TCP 套接字服务器不发送和接收