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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接和本声明。
本文连接:https://blog.csdn.net/xi_gua_gua/article/details/56991367
QML引擎(QQmlEngine)集成了Qt元对象系统,由QObject派生的全部子类的属性、方法和信号等均可以在QML中访问。QObject是子类有多种办法将功能暴露给QML访问:
一、把C++类注册为一个可实例化的QML对象类型,调用方法跟普通的QML类型同样。
二、把C++类注册为一个单例类型,能够在QML中导入单例对象实例
三、把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代码中建立ui

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


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

一、把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);blog

    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属性的写操做
                                      }  


二、把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

相关文章
相关标签/搜索