赞
踩
1、 创建继承自QObject的C++类,对象必须继承自QObject才能在QML被使用和访问
2、在类定义中使用Q_PROPERTY导出成员的READ、WRITE、NOTIFY接口,这样类中的成员变量就可以在QML调用和修改了,同时变量被修改后也会发送信号通知QML端。用 Q_INVOKABLE 修饰成员函数,这样类中的成员函数就可以直接被QML调用。前提是该模块已经被注册过!!!
- class MyObject : public QObject
- {
- Q_OBJECT
-
- public:
- explicit MyObject(QObject *parent = nullptr);
- ~MyObject();
- static MyObject * getInstance();
-
- //读取函数,对应READ
- int getIValue();
- QString getSStr();
-
- //被 Q_INVOKABLE 修饰C++函数能直接被QML调用
- Q_INVOKABLE void setCapture(bool state);
-
- //写函数,对应 WRITE,可以没有
- Q_INVOKABLE void setIValue(int value);
- Q_INVOKABLE void setSStr(const QString &str);
-
- //定义公有的槽函数
- public slots:
- Q_INVOKABLE void cppSlot(int i, QString s);
-
- private slots:
- void timer_timeout();
-
- signals:
- //修改通知,对应 NOTIFY,可以没有。可以分开写,也可以用同一个信号
- void iValueChanged(int value);
- void sStrChanged(const QString &str);
- void myObjDataChanged();
- void cppSig(QVariant i, QVariant s);
-
- private:
- QTimer *timer;
- int iValue;
- QString sStr;
-
- // property declarations required for QML
- Q_PROPERTY(int iValue READ getIValue WRITE setIValue NOTIFY myObjDataChanged)
- Q_PROPERTY(QString sStr READ getSStr WRITE setSStr NOTIFY myObjDataChanged)
- };
3、注册模块
- QQmlApplicationEngine engine;
- //1、使用setContextProperty设置全局对象/上下文对象。作用域为全局
- //常用于一些不变的常量
- QQmlContext *context = engine.rootContext();
- context->setContextProperty("SCREEN_WIDTH", 800);
- //2、使用qmlRegisterType注册模块,在qml中通过 import 模块名称 进行引用
- //模块名称、主版本号、次版本号、类名称
- qmlRegisterType<MyObject>("MyObj11", 1, 0, "MyObject");
4、QML端调用
- //创建MyObject对象
- MyObject{
- objectName: "myobj"
- //可直接操作MyObject类中的数据了
- id: myobj
- iValue: 10
- sStr: "dhl"
- Component.onCompleted:{
- console.log(iValue, sStr)
- }
- }
- //监控myobj.iValue的改变
- onValueChanged: {
- console.log("onValueChanged: ", value)
- }
-
- //1、直接访问C++的成员变量和成员函数....................................
- Button{
- id: btn1
- objectName: "button1"
- x:20; y:20
- anchors.margins: 10
- text: "访问C++成员和方法"
- onClicked: {
- myobj.iValue += 2 //修改myobj.iValue的值
- onoff = onoff ? 0 : 1
- myobj.setCapture(onoff) //调用C++端函数
- }
- }
可有两种方法可绑定QML端信号与C++端槽函数,分别在C++端绑定和在QML端绑定。需要注意的是:方式1实际是在QML信号的槽函数中调用的C++端槽函数,相当于是间接的绑定C++端的槽函数
- //2、QML端发送信号绑定C++端槽函数....................................
- signal qmlSig(int i, string s)
- Button{
- id: btn2
- objectName: "button2"
- x:200; y:20
- anchors.margins: 10
- text: "QML端发送信号绑定C++端"
- onClicked: {
- qmlSig(1, "qml signal--->cpp slot") //发送信号
- }
- }
- //方式1:在QML中使用Connections连接
- // Connections {
- // target: root
- // onQmlSig:{ //QML信号为 qmlSig(int i, string s)
- // myobj.cppSlot(i, s)
- // }
- // }
- //方式2:在QML中使用信号的connect方法
- Component.onCompleted: {
- qmlSig.connect(myobj.cppSlot)
- }
- //方式3:在C++中绑定
- //详见 main.cpp
可有两种方法可绑定C++端信号与QML端槽函数,分别在C++端绑定和在QML端绑定。需要注意的是:
1、QML中槽函数的参数类型对应c++端的必须都是QVariant!!!!
2、在C++端绑定的方式,经测试,在当前版本中不好使!
- //3、C++端发送信号绑定QML端槽函数....................................
- function qmlSlot(i, s){ //参数类型对应c++端的必须都是QVariant!!!!
- console.log("qmlslot: ", i, s)
- }
- //方式1:在QML中使用Connections连接
- Connections{
- target: myobj
- onCppSig:{ //c++端信号为void cppSig(QVariant i, QVariant s),C++端发送该信号后,会执行qmlSlot函数
- qmlSlot(i, s)
- }
- }
- //方式2:在C++中绑定。经测试,此方式在当前版本中不好使!!!
- //详见 main.cpp
在C++端需要使用 QMetaObject::invokeMethod 方法来调用QML端函数
- //4、C++端直接调用QML端函数....................................
- function qmlFunc(i, s){
- return "qmlFunc success"
- }
- //详见 main.cpp
main.cpp:
- #include <QGuiApplication>
- #include <QQmlApplicationEngine>
- #include <QQmlContext>
- #include <QVariant>
- #include <QDebug>
- #include "myobject.h"
-
- int main(int argc, char *argv[])
- {
- QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- QGuiApplication app(argc, argv);
- QQmlApplicationEngine engine;
-
- //=====》C++与QML数据交互
- //1、使用setContextProperty设置全局对象/上下文对象。作用域为全局
- //常用于一些不变的常量
- QQmlContext *context = engine.rootContext();
- context->setContextProperty("SCREEN_WIDTH", 800);
- //2、使用qmlRegisterType注册模块,在qml中通过 import 模块名称 进行引用
- //模块名称、主版本号、次版本号、类名称
- qmlRegisterType<MyObject>("MyObj11", 1, 0, "MyObject");
-
- const QUrl url(QStringLiteral("qrc:/main.qml"));
- QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
- &app, [url](QObject *obj, const QUrl &objUrl) {
- if (!obj && url == objUrl)
- QCoreApplication::exit(-1);
- }, Qt::QueuedConnection);
- engine.load(url);
-
- //=====》C++与QML信号槽绑定
- auto list = engine.rootObjects();
- auto window = list.first();
- // auto buttonObj = list.first()->findChild<QObject *>("button1");
- //绑定qml信号与c++槽
- // QObject::connect(window, SIGNAL(qmlSig(int,QString)),
- // MyObject::getInstance(), SLOT(cppSlot(int,QString)));
- //绑定c++信号和qml槽
- // QObject::connect(MyObject::getInstance(), SIGNAL(cppSig(QVariant,QVariant)),
- // window, SLOT(qmlSlot(QVariant, QVariant)));
-
- //=====》C++直接调用QML函数
- QVariant res;
- QVariant arg1 = 123;
- QVariant arg2 = "dhl";
- QMetaObject::invokeMethod(window, "qmlFunc",
- Q_RETURN_ARG(QVariant,res),
- Q_ARG(QVariant, arg1),
- Q_ARG(QVariant, arg2));
- qDebug() <<"res=" << res;
-
- return app.exec();
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。