文档章节

C++与QML交互2:在QML中调用C++特性

shzwork
 shzwork
发布于 09/20 21:50
字数 1769
阅读 16
收藏 0
Qt

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xi_gua_gua/article/details/56991367
QML引擎(QQmlEngine)集成了Qt元对象系统,由QObject派生的所有子类的属性、方法和信号等都可以在QML中访问。QObject是子类有多种办法将功能暴露给QML访问:
1、把C++类注册为一个可实例化的QML对象类型,调用方法跟普通的QML类型一样。
2、把C++类注册为一个单例类型,可以在QML中导入单例对象实例
3、把C++类作为上下文属性或者上下文对象嵌入到QML中

在启动QML时,会初始化一个QQmlEngine作为QML引擎,然后使用QQmlComponent对象加载QML文档,QML引擎会提供一个默认的QQmlContext对象作为顶层执行的上下文,用来执行QML文档中定义的函数和表达式。
QQmlEngine::rootContext() 返回当前引擎QML的上下文,唯一的,QQmlContext* QQuickView::rootContext()
QQuickItem* QQuickView::rootObject() 返回当前QQuickView的根节点,也就是QML的根节点

QQmlEngine
QQmlEngine类提供了一个QML引擎,用于管理由QML文档定义的对象层次架构,QML提供了一个默认的QML上下文(根上下文,获取函数QQmlEngine::rootContext())。该上下文是QML表达式的执行环境,并且保证在使用时对象属性能够被正确更新。
QQmlEngine可以将全局设置应用到其管理下的所有QML对象,比如网络通信:QNetworkAccessManager、全局永久(整个程序生命周期)存储的文件路径(资源预加载)等

QQmlContext
QQmlContext提供了对象实例化和表达式执行所需要的上下文环境。所有的QML对象都要在特定的上下文中实例化,所有的表达式都要在特定的上下文中执行。上下文以根上下文为主组成层次结构,子上下文继承父上下文的属性,修改子上下文的属性值可以覆盖父上下文的属性值。
QQmlContext::setContextProperty()能够通过名字将数据显示绑定到上下文,定义、更新上下文的属性
【注意】使用QQmlContext::setContextProperty()显示设置对象的属性会优先于上下文对象的属性

QQmlComponent
QML文档定义的对象类型可以在运行时使用QQmlComponent类进行实例化,QQmlComponent封装了QML组件(component)的定义,可以用于加载QML文档,前提条件是需要QQmlEngine实例化QML文档中定义的对象层次结构。
QQmlComponent实例既可以使用C++直接创建,也可以通过Qt.createComponent()函数在QML代码中创建

QQmlExpression
 动态执行表达式QQmlExpression允许客户端,在C++中利用一个特定的QML上下文执行JavaScript表达式,表达式执行的结果以QVariant的形式返回,并且遵守QML引擎确定的转换规则。


二、在QML中使用C++特性
由于QML引擎与Qt元对象系统的紧密集成,QML可以直接访问QObject子类的属性、方法、信号等。
1、QML可以直接读取和修改C++的属性
2、QML可以通过JavaScript直接调用C++方法
3、QML可以接收C++的信号
由于QML和C++两者运行所需要的上下文环境不同,当QML访问C++数据时,数据的所有权还在C++,特例:就是一个显示的C++函数调用并且返回QObject类型,QML引擎访问获取数据的所有权。Qt提供了两种在QML访问C++的方法:
法1:在C++中创建一个类,注册为QML环境的一个类型,在QML中就可以使用这个类创建对象进行访问。
法2:在C++构建一个对象,把对象通过QQmlContext::setContextProperty()设置到QML的上下文,在QML中可直接使用该对象。

1、把C++创建的类设置到QML上下文
类的要求:(1)QObject类或继承QObject。(2)调用宏Q_OBJECT。这样的类能够进入Qt元对象系统,也会被QML访问。以下是QML经常访问的C++类型
(1)QML访问C++信号、槽
例子:
创建类:                                                                把类加入QML上下文:                                                                              QML中访问C++类
class MakeClass : public QObject                        QQmlEngine engine;                                                                               text = qml_make.SetStr("Hello for QML!!!");
{                                                                             MakeClass Cmake;   //类对象,在下边设置上下文                                   qml_make.SlotMake();
    Q_OBJECT                                                         engine.rootContext->setContextProperty("qml_make",&Cmake)
    public:
         Q_INVOKABLE void SetStr(QString str);

    signals:   //C++信号
          void MakeSignal(QString str);

    public slots:  //C++槽函数
          void SlotMake();
};

(2)Q_INVOKABLE 宏修饰函数,会注册到Qt元对象系统中,QML可以直接访问 ${Object}.${method}
定义函数:Q_INVOKABLE void SetStr(QString str);
QML中使用函数:text = qml_make.SetStr("Hello for QML!!!");

(3)Q_ENUMS 宏修饰枚举,会注册到Qt元对象系统中,QML可以直接访问 ${Object}.${method}
定义枚举:Q_ENUMS(m_enum);
QML中使用枚举:text = qml_make.m_enum;

(4)Q_PROPERTY 宏修饰属性,会注册到Qt元对象系统中,QML可以对属性进行访问、修改、属性改变发送信号等操作。
定义属性:Q_PROPERTY(QString Test                //定义一个QString类型的Text属性
                                             READ GetTest         //定义读操作                                                  
                                             WRITE SetText        //定义写操作
                                             NOTIFY SlotTextChanged      //定义关联信号,当属性发生改变时,触发信号
)
QML中使用属性:text = qml_make.GetText;    //调用C++中Text属性的读操作
                         Component.onCompleted: {
                               qml_make.SetText = "Text for QML"    //调用C++中Text属性的写操作
                                      }  


2、把C++对象注册到QML中,当做一个QML对象
QObject 类或 QObject 子类都可以注册到QML中,在QML中当做一个对象类型进行实例化
注册QML类型有多个方法:
(1)qmlRegisterSingletonType()            注册一个单例类型
(2)qmlRegisterType()                             注册一个非单例类型
(3)qmlRegisterTypeNotAvailaible()      注册一个类型用来占位
(4)qmlRegisterUncreatableType()        注册一个具有附加属性类型

例子:
(1)创建类:                                                                                                                                              
class MakeClass : public QObject                                                                                                       
{                                                                                                              
    Q_OBJECT                                                         
    public:                                                               
         Q_INVOKABLE void SetStr(QString str);

         Q_PROPERTY(QString Test                //定义一个QString类型的Text属性
                                             READ GetTest         //定义读操作                                                  
                                             WRITE SetText        //定义写操作
                                             NOTIFY SlotTextChanged      //定义关联信号,当属性发生改变时,触发信号

    signals:   //C++信号
          void MakeSignal(QString str);

    public slots:  //C++槽函数
          void SlotMake();
};

(2)在main函数把类注册到QML中,注册函数要放到QML上下文创建之前,否则注册不成功:
qmlRegisterType<MakeClass>("For.Qt.MakeClass" , 1, 0, "MakeClassQml");      //把类MakeClass注册到QML中的包为:For.Qt.MakeClass, 版本:1.0, 类型为:MakeClassQml
QQuickView view; 
view.setSource( QUrl(QStringLiteral("qrc:///main.qml")));  
view.show();  

(3)QML引入并且访问C++对象类型
import For.Qt.MakeClass 1.0 
Item
{
    MakeClassQml{                   
          SetText : "Hello for QML"   //C++属性的写操作
    }
}

————————————————
版权声明:本文为CSDN博主「西_瓜_瓜」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xi_gua_gua/article/details/56991367

本文转载自:https://blog.csdn.net/xi_gua_gua/article/details/56991367

shzwork
粉丝 15
博文 817
码字总数 10675
作品 0
厦门
私信 提问
人脸识别系统开发(3) -- C++与QML混合编程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/china_jeffery/article/details/78954822 使用Qt Quick技术...

shzwork
09/24
18
0
Qt Quick 之 QML 与 C++ 混合编程详解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/foruok/article/details/32698603 Qt Quick 技术的引入,使...

shzwork
09/23
18
0
QML入门教程之 Hello world

QML是什么? QML是一种描述性的脚本语言,文件格式以.qml结尾。语法格式非常像CSS(参考后文具体例子),但又支持javacript形式的编程控制。 它结合了QtDesigner UI和QtScript的优点。QtDesig...

红薯
2011/06/02
978
0
如何使用 Qt 开发音视频通话应用

作者:单辉,声网 Agora 高级开发工程师。 众所周知,Qt 是一个跨平台的 C++ 图形用户界面应用程序开发框架,它具有跨平台、丰富的 API、支持 2D/3D 图形渲染、支持 OpenGL、开源等优秀的特性...

声网Agora
05/29
0
0
Qt 5.13.0 Beta1 发布,RC 将于5月份推出

Qt 框架于昨天发布了 5.13.0 的首个测试版本 Beta 1。官方表示,在发布候选版前,会定期发布 Beta N 更新。预计于2019年5月7日发布首个 RC 版,详情请查看时间表。 接下来不妨看看 Qt 5.13 ...

局长
03/21
1K
3

没有更多内容

加载失败,请刷新页面

加载更多

浅谈Visitor访问者模式

一、前言 什么叫访问,如果大家学过数据结构,对于这点就很清晰了,遍历就是访问的一般形式,单独读取一个元素进行相应的处理也叫作访问,读取到想要查看的内容+对其进行处理就叫作访问,那么...

青衣霓裳
19分钟前
4
0
JS内嵌多个页面,页面之间如何更快捷的查找相关联的页面

假设parent为P页面, P页面有两个子页面,分别为B页面和C页面; B页面和C页面分别内嵌一个iframe,分别为:D页面和E页面 现在通过B页面的内嵌页面D的方法refreshEpage(eUrl)来加载内嵌页面E的内容...

文文1
20分钟前
5
0
Hibernate 5 升级后 getProperties 错误

升级到 Hibernate 5 后,提示有错误: org.hibernate.engine.spi.SessionFactoryImplementor.getProperties()Ljava/util/Map; 完整的错误栈为: java.lang.NoSuchMethodError: org.hibernate......

honeymoose
22分钟前
4
0
mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
25分钟前
5
0
Spring中BeanFactory与FactoryBean的区别

在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混。 一、BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定...

大王叫下
27分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部