介绍

QML和 C++对象可以通过,signals,slots和 属性修改进行交互。对于一个C++对象,任何数据都可以通过Qt的 Meta-Object System暴露给QML(何总方法,后面介绍),同时,任何的QML对象数据通过Meta-object system在C++端直接访问。
在实际的项目中很多地方会用到QML与Qt C++交互。在这里总结了若干方法供大家参考,欢迎大家指导和拍砖。

在这里不外乎有三种方法:
1. 把Qt C++中的对象或类型暴露给 QML端,供QML端使用。(官方说法是“嵌入”而非“暴露”,比较文明。- -b)
2. QML中的Signal Handler(相当于Qt C++发送信号给QML端,QML端的Signal Handler进行处理)。
3. 在Qt C++端创建QML对象,既然对象都有了。那你想怎么样它就怎么样它呗。(没用过,看起来也不太实用,不过介绍介绍,有用过的同学留言哈)。

好,我们开始吧~

知识准备

别急,让我们先来看看,一些东西,如果您都知道,可以跳过此节。
QML API有三个主要成员——QDeclarativeEngine,QDeclarativeComponent和QDeclarativeContext。

QDeclarativeEngine提供了QML的运行环境。
QDeclarativeComponent封装了QML Documents。
QDeclarativeContext允许程序使用QML组件显示数据。

QML包含一个非常好用的API——QDeclarativeView。通过它,应用程序可以很方便的把QML组件嵌入到QGraphicsView中。QDeclarativeView主要用于在应用程序开发过程中进行快速原型开发。

暴露Qt C++的对象或类型给QML

创建需要暴露给QML的数据类型
#ifndef MYCLASS_H#define MYCLASS_H#include <QObject>#include <QString>class MyClass : public QObject{Q_OBJECTQ_PROPERTY(QString myString READ myString WRITE setmyString NOTIFY myStringChanged)public:explicit MyClass(QObject *parent = 0);Q_INVOKABLE QString getMyString();signals:void myStringChanged();public slots:void setmyString(QString aString);QString myString();private:QString m_string;};#endif // MYCLASS_H

若你想数据元素中的方法可以被QML直接调用有2种方法:
1. 在函数申明前添加 Q_INVOKABLE 宏。
2. 申明成public slots。

QML可以直接访问改数据元素的属性,该属性由QPROPERTY所申明。
具体实现请参考,示例代码。

暴露已存在的Qt C++对象给QML
//main.cppMyClass myObj;QDeclarativeEngine *engine=viewer.engine();QDeclarativeContext *context=engine->rootContext();context->setContextProperty("myObjectExposeByCXProperty", &myObj);

qml中可以直接使用myObjectExposeByCxProperty对象。

//mainpage.qml...Button{...id:btn1...text: qsTr("PROPERTY") //此处调用myString为MyClass的QPROPERTY的属性不是方法,所以没有括号。onClicked: label.text=myObjectExposeByCXProperty.myString;}...
 
注册Qt C++类类型给QML
另外一种方式是注册类型
//main.cppqmlRegisterType<MyClass>("RegisterMyType", 1, 0, "MyClassType");
QML中这样使用
//mainpage.qml...import RegisterMyType 1.0Button{id:btn2...text: qsTr("INOVKABLE")//此处调用的时INVOKABLE的方法,不是属性,所以有括号。onClicked: label.text=myclassExposeByRegType.getMyString();}//创建对象,由于QML是解释执行的,所以放后面也没什么关系。MyClassType{id:myclassExposeByRegType}
步骤:1. 导入import。2. 创建对象。3. id直接使用。

QML中的Signal Handler

还是使用上面的那例子,在qml中点击按钮控件,改变其中对象的字符串,这时候在Qt C++中发送一个signal信号给qml端,qml端接收到使用signal handler响应,改变label2的值。具体代码如下。qml中修改string的值。
//mainpage.qmlButton{id:btn3text: qsTr("emit stringchanged signal")onClicked: myObjectExposeByCXProperty.myString="xxxxx"; }
Qt C++触发信号
//myclass.cppvoid MyClass::setmyString(QString aString){if(aString==m_string){return;}m_string=aString;emit myStringChanged();}
连接signal handler响应
//mainpage.qmlConnections{target: myObjectExposeByCXPropertyonMyStringChanged:label2.text="Signal handler received" }

有参数形式的:

基本思路与具体步骤

基本思路,把你的Qt C++中的对象暴露给QML端,然后利用signals-slots 进行连接,并传递消息。具体步骤如下
1 创建自己的对象,如果你的对象是要显示在QML端,可以继承QDeclarativeItem,如果只是一个控制类,而不需要显示在QML端,只需要继承QObject。这里用到数据绑定请参考Using QML Bindings in C++ Applications

#include<QObject>class NetConnectController : public QObject{Q_OBJECTQ_PROPERTY(int status READ status WRITE setStatus NOTIFY statusChanged) public:explicit NetConnectController(QObject *parent = 0);

void Ready(){emit statusChanged( m_status);}signals:void statusChanged(int aStatus);private:int status() const;void setStatus(int aStatus);private ://表示网络不同的状态int m_status;};

2 暴露你的对象给QML

..... NetConnectController netControllerQDeclarativeEngine * engine = viewer.engine();(engine->rootContext())->setContextProperty("NetController",&netController);.....

3在QML中连接Signal-slot

......

Connections{target: NetControlleronStatusChanged:changeStatus(aStatus)//Call JS Function}......

注意:上面的onStatusChanged 命名格式 “on”+"Qt C++中的signal名字"。在QML端可以直接使用Qt C++端的参数。例如上面的"aStatus"。

Qt C++中直接调用QML的函数

同样的QML的函数也可以被Qt C++端调用。所有的QML函数都通过meta-object system暴露Qt C++端,在Qt C++端可以使用QMetaObject::invokeMethod()方法直接调用。下面就是这样的一个例子。
// MyItem.qmlimport QtQuick 1.0Item {function myQmlFunction(msg) {console.log("Got message:", msg)return "some return value"}}
// main.cppQDeclarativeEngine engine;QDeclarativeComponent 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;
注意:QMetaObject::invokeMethod()方法中的参数Q_RETURN_ARG()和Q_ARG()都被定义为QVariant类型,此类型是QML函数的的参数和返回值的通用数据类型。 更多例程可以在SDK的安装目录中:\QtSDK\Examples\4.7\declarative\tutorials\extending 看到。

QML与Qt C++ 交互机制探讨与总结相关推荐

  1. QML与Qt C++ 交互机制详解

    介绍 QML和 C++对象可以通过,signals,slots和 属性修改进行交互.对于一个C++对象,任何数据都可以通过Qt的 Meta-Object System暴露给QML(何总方法,后面介绍) ...

  2. QML(Qt Quick) 按钮设计指南

    Qt Quick 按钮设计指南 一.Qt Quick简介(Introduction to Qt Quick) 1.1 Qt Quick的历史与发展(History and Development of ...

  3. Qt Widgets、QML、Qt Quick的概念与区别

    1 QML 和 Qt Quick 是什么关系? 从概念上区分 QML 是一种用户界面规范和标记语言,它允许开发/设计人员创建高性能.流畅的动画和具有视觉吸引力的应用程序. 这里,主要涉及两点: 用户界 ...

  4. Qt Widgets、QML、Qt Quick 的区别

    作者: 一去.二三里 个人微信号: iwaleon 微信公众号: 高效程序员 在接触 Qt 之后,很多人难免会有一些疑惑: Q1:QML 和 Qt Quick 之间有什么区别? Q2:QtQuick ...

  5. QML和Qt Quick

    什么是 QML? Qt Meta-Object Language,Qt元对象语言,是一种用于描述应用程序用户界面的声明式编程语言,使用一些可视组件以及这些组件之间的交互来描述用户界面.QML是一种高可 ...

  6. (译)通过WebChannel/WebSockets与QML中的HTML交互

    来源:通过WebChannel/WebSockets与QML中的HTML交互 GitHub:八至 作者:狐狸家的鱼 本文链接:QML与HTML交互 在查询QML与HTML之间通信交互时资料很少,这篇文 ...

  7. 英文文章:中国国家医疗联合体的演化路径和内部交互机制研究:基于复杂系统理论的分析

    1.研究问题是什么?(从现象出发) 这篇文章考虑到我国存在很多类型的医院,按照国家的制度设计,不同类型的医院应该承载着不同的功能,比如城镇医院主要治普通疾病,三级医院专治疑难杂症,专业公共卫生机构主要 ...

  8. [z]Qt 内存管理机制

    文章只是简要的介绍了Qt的内存管理机制,对理解内存管理比较有帮助 强类型语言在创建对象时总会显式或隐式地包含对象的类型信息.也就是说,强类型语言在分配对象内存空间时,总会关联上对象的类型.相比之下,弱 ...

  9. QT每日一练day2:day1优化以及QT内存管理机制

    QT中的继承关系 day1优化   一般我们不直接用QWidget来实例化对象,用它的派生类来生成对象,main函数中一般不写太多代码,都是在派生类的构造函数中进行窗口的初始化.布局.设置.其子窗口设 ...

最新文章

  1. .NET CORE MYSQL 微信小程序 HTTPS 随笔
  2. Python在线考试系统防作弊功能的思路和实现
  3. MySQL 字段内容区分大小写
  4. Python中[index for index, value in enumerate(a) if value > 3]
  5. leetcode笔记(Python版)待更新
  6. Jtable 表格按多列排序(支持中文汉字排序)
  7. 思科模拟器静态路由设置,以及rip路由设置
  8. 大学计算机网络实验网线制作,计算机网络实验报告 网线的制作.doc
  9. Android自定义View、ViewGroup
  10. 英语:逆向忠言(转载)
  11. BlackBerry手机应用上网的通道列表
  12. 莫队算法完整总结(普通莫队、带修莫队、树上莫队、回滚莫队)
  13. kubernetes apiserver源码分析二之路由
  14. 网上书城之门户首页及新书上架,热销书籍
  15. 最简单的 DRM 应用 drm设备不工作
  16. Spark 3.x各模式部署 - Ubuntu
  17. 江湖云RFID电子标签在珠宝行业的应用
  18. 形式语言与自动机——第三章 上下文无关文法与下推自动机
  19. 学术论文等级与分类标准——JCR
  20. Core Fusion- Accommodating Software Diversity in Chip Multiprocessors .md

热门文章

  1. AI+医疗:基于模型的医疗应用大规模分析 | 腾讯AI Lab学术论坛演讲
  2. 2017全球大数据产业八领域典型公司盘点分析
  3. 隐藏十年竟无人发现!Sudo 漏洞被曝出:无需密码就能获取 root 权限
  4. 时间管理大师!一程序员同时给谷歌和 Facebook 打工??
  5. 一周内咸鱼疯转 2.4W 次,最终被所有大厂封杀!
  6. 说说设计模式~建造者模式(Builder)
  7. Wireshark默认不抓取本地包的解决方式
  8. vue.js 初体验— Chrome 插件开发实录
  9. 例5.12 输入一串字符,字符个数不超过100,且以.结束。 (信息学奥赛一本通)...
  10. 毕业一年左右的前端妹子面经总结