QML与C++的集成

QML与C++

QML引擎与Qt的元对象系统的集成,使得QML中可以直接调用C++的功能。
只有QObject子类才能够将数据或者函数提供给QML使用。由于QML引擎集成了Qt元对象系统,由QObject派生的所有子类的属性、方法和信号灯都可以在QML中访问。

  • C++类可以被注册为一个可实例化的QML类型,这样他就可以像其它普通QML对象类型一样在QML代码中被实例化使用
  • C++类可以被注册为一个单例类型,这样可以在QML代码中导入这个单例对象实例
  • C++类的实例可以作为上下文属性或者上下文对象嵌入到QML代码中。

除了可以从QML中访问C++的功能,在Qt QML模块中也提供了多种方式从C++代码中操作QML对象。

QML运行时的C++类

Qt QML模块提供的一些实现了QML框架的C++类。客户端可以使用这些类与QML进行时进行交互(如向对象注入数据,或者调用对象方法),并且从QML文档实例化一个对象树状结构。

QML应用程序构成一个QML客户端,在启动时候,客户端会初始化一个QQmlEngine类作为QML引擎,然后使用QQmlComponent对象加载QML文档。
QML引擎会提供一个默认的QQmlContext对象作为顶层执行上下文,用来执行QML文档中定义的函数和表达式。这个上下文可以通过QQmlEngine::rootContext()函数获取,利用QML引擎可以对其进行修改等操作。

QQmlEngine

QQmlEngine允许将全局设置应用到其管理的所有对象。如用于网络通信的QNetworkAccessManager以及用于永久存储的文件路径。
在QQmlApplicationEngine类,它是QQmlEngine的子类。QQmlApplicationEngine结合了QQmlEngine和QQmlComponent的功能,提供了一种简便的方式实现了从一个单一的QML文件加载一个应用程序。

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
//load()函数会自动加载给定的文件并立即创建文件中定义的对象树。

QQmlContext

QQmlContext提供了对象实例化和表达式执行所需要的运行时上下文。所有对象都需要在一个特定的上下文中实例化,所有表达式都要在一个特定的上下文中执行。QQmlContext类在QML引擎中定义了这样一个上下文,允许数据暴露给由QML引擎实例化的QML组件。
QQml组件Context包含了一系列属性,能够通过名字将数据显式绑定到上下文。可以使用QQmlContext::setContextProperty()函数来定义、更新上下文中的属性。
如:

    QQmlEngine engine;
    QStringListMOdel modelData;
    QQmlContext * context=engine.rootContext();
    context->setContextProperty ("stringModel",&modelData); 
//QQmlContext对象作为顶层执行上下文,用来执行QML文档中定义的函数或者表达式。

//根上下文创建了一个新的上下文对象
//这里是由根上下文创建了一个新的上下文对象。modelData被添加到新的上下文中,并且该上下文作为动态创建的组件上下文。以

    QQmlEngine engine;
    QStringListMOdel modelData;
    QQmlContext * context=new QQmlContext(engine.rootContext());
    context->setContextProperty("stringModel",&modelData);
QQmlComponent component(&engine);
component.setData("import QtQuick 2.2\nListView"{
model:stringModel}",QUrl());
    QObject *window=component.create(context);

QQmlExpression

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

import QtQuick 2.2
Item{
    width:200;
    height:200
}

//可以使用下面的C++代码,在上下文中执行Js表达式

QQmlEngine *engine=new QQmlEngine;
QQmlComponent component (engine,QUrl::fromLocalFile("main.qml"));

QObject * object=component,create();

QQmlExpression *expr=new QQmlExpression(
engine->rootContext(),object,"width *2");

int result=expr->evaluate().toInt();

在QML中使用C++特性

QML引擎和元对象系统的紧密集成,QML可以非常方便地通过C++进行扩展。QML可以直接访问QObject子类的属性、方法和信号:属性可以在QML中读取和修改;方法可以直接通过Js调用;信号处理函数则根据信号自动创建。

使用枚举类型

使用Q_ENUMS宏将枚举注册到Qt元对象系统。

使用C++属性

QObject子类的所有属性都能够被QML访问。
QObject子类使用Q_PROPERTY宏定义一个属性,该宏的作用是向Qt元对象系统注册类的属性。一个类的属性就是类的数据成员,通常会有一个用于读取的READ函数和一个可选的用于修改的WRITE函数。

class Mesage :public QObject{
    Q_OBJECT
    Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
    public :
        void setAuthor(const QString &a){
            if(a!=m_author){
                m_author=a;
                emit authorChanged();
            }
        } 
    QString author() const{
        return m_author;
    }
    signals:
        void authorChanged();
    private:
        QString m_author;
} ;

在使用时,可以将Message类的一个实例作为加载QML文档myItem.qml的上下文属性:

int main(int argc,char *argv[]){
    QCoreApplication app(argc,argv);
    QQmlEngine engine;
    Message msg;
    engine.rootContext()->setContextProperty("msg",&msg);
    QQmlComponent component(&engine,QUrl::fromLocalFile("myItem.qml"));
    component.create();
    return app.exec()
}



//然后可以在myItem.qml中直接操作author属性
import QtQuck 2.2
Text{
    width:100 ; height:100
    text:msg..author  //会调用Message::author()
    Component.onCompleted:{
        msg.author="Jonah"; //调用MEssage::setAuthor()
    }
}

为了尽可能增强与QML的可交互性,任何可写属性都应该关联一个NOTIFY信号。
如上面属性author有一个NOTIFY信号authorChanged()。当setAuthor()函数修改了author()属性时候,该信号便会发出。

NOTIFY信号的确会产生不小开销。有些属性值仅在对象构造时候设置,之后就不会被修改。此时应该使用CONSTRANT特性而不是NOTIFY。

本文适合于对Qt Quick有基本了解的读者。首先回答一个比较常会被问到的问题:什么是QML,它与Quick的关系是什么? Qt Quick是Qt User Interface Creation Kit的缩写,而QMLQt Quick最重要的组成部分,Qt Quick结合了如下技术: 组件集合,其中大部分是关于图形界面的 基于JavaScript陈述性语言:QMLQt Meta-Object Language的缩写) 用于管理组件并与组件交互的C++ API - QtDeclarative模块 言归正传:通过Qt Creator,我们可以轻松生成一个Qt Quick的应用工程,从而为QML生成应用程序框架。具体操作详见:创建qt quick (qml) 应用程序。 C++QML的交互是通过注册C++对象给QML环境得以实现的: 在C++实现中,非可视化的型别均为QObject的子类,可视化的类型均为QDeclarativeItem的子类。注意:QDeclarativeItem等同于QML的Item类。 如果用户想要定义自己的型别,做法如下: 在C++中,实现派生于QObject或QDeclarativeItem的子类,它是新定义item的实体对象; 在C++中,将1中实现的新item类型注册给QML; 在QML中,导入含有1中定义的新item的模块; 在QML中,向使用标准的item一样使用新定义的item 现举例说明,我们现尝试使用用Qt C++实现的MyButton对象(如下qml代码),它有自己的属性、方法以及信号的handler。用法如下(它与使用其它标准的QML item一样),所需要做的是 需要导入包含MyButton的对应模块名称及其版本“MyItems 1.0 ”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值