Qt中C++与Qml互相调用
QML调用C++
思路
一种解决方案:
使用Qt中的QML调用C++中的类,首先使用需要定义一个继承自 QObject
的类,然后将这个类注册到 QML 中去,然后在这个类使用 Q_INVOKABLE
这个宏修饰的函数,都可以直接在QML中调用。
示例:
## 0x01 定义一个C++类 #include <QObject> #include <QDebug> class QmlBrg : public QObject { Q_OBJECT public: explicit QmlBrg(QObject *parent = nullptr); Q_INVOKABLE void ssss() const noexcept { qDebug() << "qml确实调我了!"; } signals: }; ## 0x02 注册到QML中去 QmlBrg* qbrg = new QmlBrg; /** 在QML中这个实例名就叫 cbrg **/ qmlwid->rootContext()->setContextProperty("cbrg", qbrg); ### 0x03 在QML中调用 onClicked: { console.log("我要调用 C++ !") cbrg.ssss(); }
C++调用 QML
https://blog.csdn.net/baidu_33850454/article/details/81941675
1.1通过 objectName 来获取QML对象
假设MyItem.qml的内容如下,Item中存在一个objectName为“rect”的矩形
import QtQuick 2.0 Item { width: 100; height: 100 Rectangle { anchors.fill: parent objectName: "rect" } }
则 上述 矩形可以通过 如下方式获取:
QObject *rect = object->findChild<QObject*>("rect"); if (rect) rect->setProperty("color", "red");
如果存在多个objectName相同的对象,比如listView的Delegate中设置了一个特定的对象名称,则可以使用QObject::findChildren()来获取所有子对象。
警告: 尽管可以从C++中获取和操作QML对象,但是除非为了测试和原型设计,并不建议这样做。因为QML和C ++集成的优势之一是能够在QML中实现与C ++逻辑和后端分离的UI。
1.2从C ++访问QML对象类型的成员
在QML中使用property声明的属性可以在C++中被获取。假设MyItem.qml的内容如下:
// MyItem.qml import QtQuick 2.0 Item { property int someNumber: 100 } 则someNumber属性值可以通过QQmlProperty,QObject::setProperty() 和QObject::property()来访问。 QQmlEngine engine; QQmlComponent component(&engine, "MyItem.qml"); QObject *object = component.create(); qDebug() << "Property value:" << QQmlProperty::read(object, "someNumber").toInt(); QQmlProperty::write(object, "someNumber", 5000); qDebug() << "Property value:" << object->property("someNumber").toInt(); object->setProperty("someNumber", 100);
注意:你必须通过QObject::setProperty(), QQmlProperty or QMetaProperty::write()这三种方法来设置QML的属性,才能够保证QML引擎对你的修改可知。
2、调用QML函数
所有的QML函数都暴露在Qt元对象系统中,可以被C++使用QMetaObject::invokeMethod()来访问。向QML传递的函数参数和QML的返回值需要在C ++中转换为QVariant值,因为这是QML函数参数和返回值的通用数据类型。例如:
// MyItem.qml import QtQuick 2.0 Item { function myQmlFunction(msg) { console.log("Got message:", msg) return "some return value" } } C++ 代码如下: // main.cpp QQmlEngine engine; QQmlComponent component(&engine, "MyItem.qml"); QObject *object = component.create(); QVariant returnedValue; QVariant msg = "Hello from C++"; QMetaObject::invokeMethod(object, "myQmlFunction", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, msg)); qDebug() << "QML function returned:" << returnedValue.toString(); delete object;
13
3、连接QML信号
所有的QML信号均可以在C++中被访问,可以像普通Qt的C++信号一样使用。
QML信号参数为string:
// MyItem.qml import QtQuick 2.0 Item { id: item width: 100; height: 100 signal qmlSignal(string msg) MouseArea { anchors.fill: parent onClicked: item.qmlSignal("Hello from QML") } }
C++处理方式如下:
class MyClass : public QObject { Q_OBJECT public slots: void cppSlot(const QString &msg) { qDebug() << "Called the C++ slot with message:" << msg; } }; int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQuickView view(QUrl::fromLocalFile("MyItem.qml")); QObject *item = view.rootObject(); MyClass myClass; QObject::connect(item, SIGNAL(qmlSignal(QString)), &myClass, SLOT(cppSlot(QString))); view.show(); return app.exec(); }
需要注意的是,当信号参数时QML对象时,参数类型应该为var,C++中槽函数的参数应该为QVariant。
QML文件如下:
// MyItem.qml import QtQuick 2.0 Item { id: item width: 100; height: 100 signal qmlSignal(var anObject) MouseArea { anchors.fill: parent onClicked: item.qmlSignal(item) } }
则C++处理方式如下:
class MyClass : public QObject { Q_OBJECT public slots: void cppSlot(const QVariant &v) { qDebug() << "Called the C++ slot with value:" << v; QQuickItem *item = qobject_cast<QQuickItem*>(v.value<QObject*>()); qDebug() << "Item dimensions:" << item->width() << item->height(); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); QQuickView view(QUrl::fromLocalFile("MyItem.qml")); QObject *item = view.rootObject(); MyClass myClass; QObject::connect(item, SIGNAL(qmlSignal(QVariant)), &myClass, SLOT(cppSlot(QVariant))); view.show(); return app.exec(); }
参考链接:http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2020-03-25 CentOS8安装mysql