首页 > 编程 > C++ > 正文

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

2019-11-07 23:45:19
字体:
来源:转载
供稿:网友
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的根节点QQmlEngineQQmlEngine类提供了一个QML引擎,用于管理由QML文档定义的对象层次架构,QML提供了一个默认的QML上下文(根上下文,获取函数QQmlEngine::rootContext())。该上下文是QML表达式的执行环境,并且保证在使用时对象属性能够被正确更新。QQmlEngine可以将全局设置应用到其管理下的所有QML对象,比如网络通信:QNetworkaccessManager、全局永久(整个程序生命周期)存储的文件路径(资源预加载)等QQmlContextQQmlContext提供了对象实例化和表达式执行所需要的上下文环境。所有的QML对象都要在特定的上下文中实例化,所有的表达式都要在特定的上下文中执行。上下文以根上下文为主组成层次结构,子上下文继承父上下文的属性,修改子上下文的属性值可以覆盖父上下文的属性值。QQmlContext::setContextPRoperty()能够通过名字将数据显示绑定到上下文,定义、更新上下文的属性【注意】使用QQmlContext::setContextProperty()显示设置对象的属性会优先于上下文对象的属性QQmlComponentQML文档定义的对象类型可以在运行时使用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, 类型为:MakeClassQmlQQuickView 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++属性的写操作    }}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选