当前位置:   article > 正文

QML学习笔记【06】:QML与C++交互_qml qqmlapplicationengine connect

qml qqmlapplicationengine connect

1 QML端直接调用C++端变量及函数

1、 创建继承自QObject的C++类,对象必须继承自QObject才能在QML被使用和访问

2、在类定义中使用Q_PROPERTY导出成员的READ、WRITE、NOTIFY接口,这样类中的成员变量就可以在QML调用和修改了,同时变量被修改后也会发送信号通知QML端。用 Q_INVOKABLE 修饰成员函数,这样类中的成员函数就可以直接被QML调用。前提是该模块已经被注册过!!!

  1. class MyObject : public QObject
  2. {
  3. Q_OBJECT
  4. public:
  5. explicit MyObject(QObject *parent = nullptr);
  6. ~MyObject();
  7. static MyObject * getInstance();
  8. //读取函数,对应READ
  9. int getIValue();
  10. QString getSStr();
  11. //被 Q_INVOKABLE 修饰C++函数能直接被QML调用
  12. Q_INVOKABLE void setCapture(bool state);
  13. //写函数,对应 WRITE,可以没有
  14. Q_INVOKABLE void setIValue(int value);
  15. Q_INVOKABLE void setSStr(const QString &str);
  16. //定义公有的槽函数
  17. public slots:
  18. Q_INVOKABLE void cppSlot(int i, QString s);
  19. private slots:
  20. void timer_timeout();
  21. signals:
  22. //修改通知,对应 NOTIFY,可以没有。可以分开写,也可以用同一个信号
  23. void iValueChanged(int value);
  24. void sStrChanged(const QString &str);
  25. void myObjDataChanged();
  26. void cppSig(QVariant i, QVariant s);
  27. private:
  28. QTimer *timer;
  29. int iValue;
  30. QString sStr;
  31. // property declarations required for QML
  32. Q_PROPERTY(int iValue READ getIValue WRITE setIValue NOTIFY myObjDataChanged)
  33. Q_PROPERTY(QString sStr READ getSStr WRITE setSStr NOTIFY myObjDataChanged)
  34. };

3、注册模块

  1. QQmlApplicationEngine engine;
  2. //1、使用setContextProperty设置全局对象/上下文对象。作用域为全局
  3. //常用于一些不变的常量
  4. QQmlContext *context = engine.rootContext();
  5. context->setContextProperty("SCREEN_WIDTH", 800);
  6. //2、使用qmlRegisterType注册模块,在qml中通过 import 模块名称 进行引用
  7. //模块名称、主版本号、次版本号、类名称
  8. qmlRegisterType<MyObject>("MyObj11", 1, 0, "MyObject");

4、QML端调用

  1. //创建MyObject对象
  2. MyObject{
  3. objectName: "myobj"
  4. //可直接操作MyObject类中的数据了
  5. id: myobj
  6. iValue: 10
  7. sStr: "dhl"
  8. Component.onCompleted:{
  9. console.log(iValue, sStr)
  10. }
  11. }
  12. //监控myobj.iValue的改变
  13. onValueChanged: {
  14. console.log("onValueChanged: ", value)
  15. }
  16. //1、直接访问C++的成员变量和成员函数....................................
  17. Button{
  18. id: btn1
  19. objectName: "button1"
  20. x:20; y:20
  21. anchors.margins: 10
  22. text: "访问C++成员和方法"
  23. onClicked: {
  24. myobj.iValue += 2 //修改myobj.iValue的值
  25. onoff = onoff ? 0 : 1
  26. myobj.setCapture(onoff) //调用C++端函数
  27. }
  28. }

2 QML端发送信号绑定C++端槽函数

可有两种方法可绑定QML端信号与C++端槽函数,分别在C++端绑定和在QML端绑定。需要注意的是:方式1实际是在QML信号的槽函数中调用的C++端槽函数,相当于是间接的绑定C++端的槽函数

  1. //2、QML端发送信号绑定C++端槽函数....................................
  2. signal qmlSig(int i, string s)
  3. Button{
  4. id: btn2
  5. objectName: "button2"
  6. x:200; y:20
  7. anchors.margins: 10
  8. text: "QML端发送信号绑定C++端"
  9. onClicked: {
  10. qmlSig(1, "qml signal--->cpp slot") //发送信号
  11. }
  12. }
  13. //方式1:在QML中使用Connections连接
  14. // Connections {
  15. // target: root
  16. // onQmlSig:{ //QML信号为 qmlSig(int i, string s)
  17. // myobj.cppSlot(i, s)
  18. // }
  19. // }
  20. //方式2:在QML中使用信号的connect方法
  21. Component.onCompleted: {
  22. qmlSig.connect(myobj.cppSlot)
  23. }
  24. //方式3:在C++中绑定
  25. //详见 main.cpp

3 C++端发送信号绑定QML端槽函数

可有两种方法可绑定C++端信号与QML端槽函数,分别在C++端绑定和在QML端绑定。需要注意的是:

1、QML中槽函数的参数类型对应c++端的必须都是QVariant!!!!

2、在C++端绑定的方式,经测试,在当前版本中不好使!

  1. //3、C++端发送信号绑定QML端槽函数....................................
  2. function qmlSlot(i, s){ //参数类型对应c++端的必须都是QVariant!!!!
  3. console.log("qmlslot: ", i, s)
  4. }
  5. //方式1:在QML中使用Connections连接
  6. Connections{
  7. target: myobj
  8. onCppSig:{ //c++端信号为void cppSig(QVariant i, QVariant s),C++端发送该信号后,会执行qmlSlot函数
  9. qmlSlot(i, s)
  10. }
  11. }
  12. //方式2:在C++中绑定。经测试,此方式在当前版本中不好使!!!
  13. //详见 main.cpp

4 C++端直接调用QML端函数

在C++端需要使用 QMetaObject::invokeMethod 方法来调用QML端函数

  1. //4、C++端直接调用QML端函数....................................
  2. function qmlFunc(i, s){
  3. return "qmlFunc success"
  4. }
  5. //详见 main.cpp

main.cpp:

  1. #include <QGuiApplication>
  2. #include <QQmlApplicationEngine>
  3. #include <QQmlContext>
  4. #include <QVariant>
  5. #include <QDebug>
  6. #include "myobject.h"
  7. int main(int argc, char *argv[])
  8. {
  9. QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
  10. QGuiApplication app(argc, argv);
  11. QQmlApplicationEngine engine;
  12. //=====》C++与QML数据交互
  13. //1、使用setContextProperty设置全局对象/上下文对象。作用域为全局
  14. //常用于一些不变的常量
  15. QQmlContext *context = engine.rootContext();
  16. context->setContextProperty("SCREEN_WIDTH", 800);
  17. //2、使用qmlRegisterType注册模块,在qml中通过 import 模块名称 进行引用
  18. //模块名称、主版本号、次版本号、类名称
  19. qmlRegisterType<MyObject>("MyObj11", 1, 0, "MyObject");
  20. const QUrl url(QStringLiteral("qrc:/main.qml"));
  21. QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
  22. &app, [url](QObject *obj, const QUrl &objUrl) {
  23. if (!obj && url == objUrl)
  24. QCoreApplication::exit(-1);
  25. }, Qt::QueuedConnection);
  26. engine.load(url);
  27. //=====》C++与QML信号槽绑定
  28. auto list = engine.rootObjects();
  29. auto window = list.first();
  30. // auto buttonObj = list.first()->findChild<QObject *>("button1");
  31. //绑定qml信号与c++槽
  32. // QObject::connect(window, SIGNAL(qmlSig(int,QString)),
  33. // MyObject::getInstance(), SLOT(cppSlot(int,QString)));
  34. //绑定c++信号和qml槽
  35. // QObject::connect(MyObject::getInstance(), SIGNAL(cppSig(QVariant,QVariant)),
  36. // window, SLOT(qmlSlot(QVariant, QVariant)));
  37. //=====》C++直接调用QML函数
  38. QVariant res;
  39. QVariant arg1 = 123;
  40. QVariant arg2 = "dhl";
  41. QMetaObject::invokeMethod(window, "qmlFunc",
  42. Q_RETURN_ARG(QVariant,res),
  43. Q_ARG(QVariant, arg1),
  44. Q_ARG(QVariant, arg2));
  45. qDebug() <<"res=" << res;
  46. return app.exec();
  47. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/658714
推荐阅读
相关标签
  

闽ICP备14008679号