本文翻译自Using QML in C++ Applications。欢迎大家编辑、修改此文章。

QML API有三个主要成员——QDeclarativeEngine,QDeclarativeComponent和QDeclarativeContext。

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

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

如果你正打算用QML改造现有的Qt应用程序,请参考QML与Qt UI代码整合。

基本用法

若想将QML与C++程序结合,程序中至少需要一个QDeclarativeEngine。只有程序中需要使用多个不同的QML组件实例时,才需要多个QDeclarativeEngine。为了使所有QML组件实例可以工作,QDeclarativeEngine为他们提供全局配置,QDeclarativeEngine对于C++中使用QML的作用如同QNetworkAccessManager对于网络通信、路径对于持久化存储的作用。

可以使用QDeclarativeComponent加载QML Documents。每一个QDeclarativeComponent实例对应一个QML document。

可以传递一个Document URL或者表示Document内容的原始文本给QDeclarativeComponent。Document URL可以是本地文件系统URL,或者任何QNetworkAccessManager支持的网络URL。

可以通过QDeclarativeComponent::create()方法创建QML组件实例。下面的代码演示了如何加载一个QML Document并创建一个实例:

QDeclarativeEngine *engine = new QDeclarativeEngine(parent);QDeclarativeComponent component(engine, QUrl::fromLocalFile("main.qml"));QObject *myObject = component.create();

暴露数据(Exposing Data)

QML组件在QDeclarativeContext中实例化。一个上下文(context)允许程序暴露数据给QML组件实例。一个QDeclarativeContext可用于创建应用程序中用到的所有对象实例,如果需要精确控制为每个实例暴露的数据,可以创建多个QDeclarativeContex。如果上下文(context)没有传递给QDeclarativeComponent::create()方法,将默认使用QDeclarativeEngine的根上下文(root context),这时数据通过跟上下文(root context)暴露给所有对象实例。

简单数据(Simple Data)

向QML组件实例暴露数据,通过QML属性绑定(Property Bindings)和JavaScript对象访问应用程序设置上下文属性(context properties)。下面的例子展示了如何通过QDeclarativeView暴露背景颜色给QML文件:

// main.cpp #include <QApplication> #include <QDeclarativeView> #include <QDeclarativeContext>

int main(int argc, char *argv[]) {     QApplication app(argc, argv);

     QDeclarativeView view;     QDeclarativeContext *context = view.rootContext();     context->setContextProperty("backgroundColor",                                 QColor(Qt::yellow));

     view.setSource(QUrl::fromLocalFile("main.qml"));     view.show();

return app.exec(); }

// main.qml

 import QtQuick 1.0

 Rectangle {     width: 300     height: 300

     color: backgroundColor

     Text {         anchors.centerIn: parent         text: "Hello Yellow World!"     } }

如果你只希望在main.cpp里创建组件,不想显示在QDeclarativeView中,需要使用QDeclarativeEngine::rootContext()来创建QDeclarativeContext实例:

QDeclarativeEngine engine;     QDeclarativeContext *windowContext = new QDeclarativeContext(engine.rootContext());     windowContext->setContextProperty("backgroundColor", QColor(Qt::yellow));

     QDeclarativeComponent component(&engine, "main.qml");     QObject *window = component.create(windowContext);

上下文属性(Context Properties)的工作方式同QML绑定(QML bindings)中的普通属性(normal properties)一样,在上面的例子中,当上下文属性(context poperty)backgroundColor变为红色时,组件对象实例都会自动更新。请注意创建者有责任删除它创建的QDeclarativeContext。当销毁Window组件时,windowContext必须被显式的销毁(手动delete),或者用一种更简单的方法——设置windowContext的父类为window(父对象释放时,会自动释放所有子对象)。

QDeclarativeContexts以树状结构组织,除了根上下文(root context)外,每个QDeclarativeContext都有一个父对象。QDeclarativeContexts子对象有效的继承父对象的上下文属性(context properties),这使得应用程序更加灵活的在不同的QML对象实例间暴露(exposed)数据。如果QDeclarativeContext设置了一个与父对象相同的上下文属性(context property),父对象的这个属性将被“隐藏”。如下面的例子所示,Context1中的上下文属性(context property)background“隐藏”了根上下文(root context)中的background属性。

结构化数据(Structed Data)

上下文属性(context property)还可用于向QML对象暴露结构化可写数据。除了QVariant已经支持的所有类型外,派生自QObject的类型也可分配给上下文属性(context property)。QObject上下文属性(context property)允许暴露结构化的数据,并允许QML对这些数据设值。 下面的例子创建了一个CustomPalette对象,并将它设为名为palette的上下文属性(context property):

class CustomPalette : public QObject {     Q_OBJECT     Q_PROPERTY(QColor background READ background WRITE setBackground NOTIFY backgroundChanged)     Q_PROPERTY(QColor text READ text WRITE setText NOTIFY textChanged)

public:     CustomPalette() : m_background(Qt::white), m_text(Qt::black) {}

     QColor background() const { return m_background; }void setBackground(const QColor &c) {if (c != m_background) {             m_background = c;             emit backgroundChanged();         }     }

     QColor text() const { return m_text; }void setText(const QColor &c) {if (c != m_text) {             m_text = c;             emit textChanged();         }     }

 signals:void textChanged();void backgroundChanged();

private:     QColor m_background;     QColor m_text; };

int main(int argc, char *argv[]) {     QApplication app(argc, argv);

     QDeclarativeView view;     view.rootContext()->setContextProperty("palette", new CustomPalette);

     view.setSource(QUrl::fromLocalFile("main.qml"));     view.show();

return app.exec(); }

下面的QML文件使用了palette对象及它的属性来设置背景和文字颜色。当窗口被点击时,palette的颜色将被改变,窗口文本也会被相应的更新:

import QtQuick 1.0

 Rectangle {     width: 240     height: 320     color: palette.background

     Text {         anchors.centerIn: parent         color: palette.text         text: "Click me to change color!"     }

     MouseArea {         anchors.fill: parent         onClicked: {             palette.text = "blue";         }     } }

在这个例子中,当检测到C++属性值(CustomPalette的文本)改变时,该属性必须有一个相应的NOTIFY信号,当属性值改变时发送NOTIFY信号。实现的时候需要注意,仅当属性值改变时才发送信号,从而避免发生死循环。访问一个绑定的属性时,如果没有NOTIFY信号将会导致QML产生一个运行时的警告。

动态结构数据(Dynamic Structured Data)

如果一个应用程序在编译期具有很多QObject类型的动态结构化数据,可以使用QDeclarativePropertyMap在运行期动态的创建这些结构化数据。

在QML中调用C++方法

QML中可以调用QObject及其派生类对象中的public slot的方法或标记为Q_INVOKABLE的方法。

上述的C++方法可以具有参数和返回值,QML支持下列数据类型:

   * bool   * unsigned int, int   * float, double, qreal   * QString   * QUrl   * QColor   * QDate,QTime,QDateTime   * QPoint,QPointF   * QSize, QSizeF   * QRect,QRectF   * QVariant

下面的例子演示了当MouseArea被点击时,触发“Stopwatch”对象的start()/stop():

// main.cpp

class Stopwatch : public QObject {     Q_OBJECTpublic:     Stopwatch();

     Q_INVOKABLE bool isRunning() const;

public slots:void start();void stop();

private:bool m_running; };

int main(int argc, char *argv[]) {     QApplication app(argc, argv);

     QDeclarativeView view;     view.rootContext()->setContextProperty("stopwatch",new Stopwatch);

     view.setSource(QUrl::fromLocalFile("main.qml"));     view.show();

return app.exec(); }

// main.qml

 import QtQuick 1.0

 Rectangle {     width: 300     height: 300

     MouseArea {         anchors.fill: parent         onClicked: {if (stopwatch.isRunning())                 stopwatch.stop()else                 stopwatch.start();         }     } }

请注意,在这个特殊的例子中,有一个更好的方法来达到同样的结果——main.qml中可以用一个“运行中“属性(property),更漂亮的QML代码如下:

// main.qml import QtQuick 1.0

 Rectangle {     MouseArea {         anchors.fill: parent         onClicked: stopwatch.running = !stopwatch.running     } }

此外,还可以调用functions declared in QML from C++描述的方法。

网络组件(Network Components)

如果传递给QDeclarativeComponent一个网络资源,或者QML document中引用了网络资源,QDeclarativeComponent会在创建对象之前先获取网络资源数据。在这种情况下QDeclarativeComponent将有一个加载状态(Loading status)。应用程序将一直等待(在调用QDeclarativeComponent::create()之前),直到组件准备完毕。

下面的例子演示了如何加载一个网络QML文件资源。QDeclarativeComponent创建后,先检查组件是否正在加载,如果正在加载则连接QDeclarativeComponent::statusChanged()信号,否则直接调用continueLoading()方法。虽然在这个例子里已经知道URL在远程,但这个检查还是必须的,这样可以在组件已经缓存了该URL的情况下,直接创建组该件。

MyApplication::MyApplication() {// ...     component = new QDeclarativeComponent(engine, QUrl("http://www.example.com/main.qml"));if (component->isLoading())         QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),this, SLOT(continueLoading()));else         continueLoading(); }

void MyApplication::continueLoading() {if (component->isError()) {         qWarning() << component->errors();     } else {         QObject *myObject = component->create();     } }

Qt资源(Qt Resources)

QML可以通过qrc:URL从Qt资源系统(Qt Resource System)中加载,例如:

[project/example.qrc]

<!DOCTYPE RCC> <RCC version="1.0">

 <qresource prefix="/">     <file>main.qml</file>     <file>images/background.png</file> </qresource>

 </RCC>

[project/project.pro]

QT += declarative

 SOURCES += main.cpp RESOURCES += example.qrc

[project/main.cpp]

int main(int argc, char *argv[]) {     QApplication app(argc, argv);

     QDeclarativeView view;     view.setSource(QUrl("qrc:/main.qml"));     view.show();

return app.exec(); }

[project/main.qml]

import QtQuick 1.0

 Image {     source: "images/background.png" }

注意:QML中无法直接访问资源系统。如果主QML文件作为资源加载,主QML文件中的所有指定相对路径的文件都将从资源系统中加载。如果主QML文件没有作为资源加载,那么资源系统中的文件无法在QML中访问。

转载于:https://www.cnblogs.com/hicjiajia/archive/2012/01/30/2332266.html

QML基础——在C++程序中使用QML相关推荐

  1. QML基础以及Qt Quick应用

    QML基础以及Qt Quick应用 一 QML文档构成 1.import部分 2.对象声明 3.属性别名 二 QML可视元素 1.Rectangle 2.Image 3.Text 4.自定义元素(组件 ...

  2. qml基础学习 基础概念

    一.概括 学习qt已有2年多的时间,从qt4.7开始使用直到现在正在使用的qt5.6,基本都在windows机器上做开发.最近有意向看了下qt的qml部分,觉着还是挺不错的,毕竟可以做嵌入式移动端产品 ...

  3. Qt5 学习之路及嵌入式开发教程21:QML基础

    Qt5 学习之路及嵌入式开发教程21:QML基础 一.启动Qt5.12 1.新建项目文件,进入界面 2.选择后 3.几个下一步后,点击完成: 4.运行,查看结果 二.在窗口中绘制一个矩形 1.在tit ...

  4. 与C ++中的QML对象进行交互

    与C ++中的QML对象进行交互 与C ++中的QML对象进行交互 从C ++加载QML对象 通过对象名称访问已加载的QML对象 从C ++访问QML对象类型的成员 调用QML方法 连接到QML信号 ...

  5. QtQuick 中的 qml 与 Qt 的 C++

    QtQuick 可以使用内置的 JavaScript 引擎加载相应的 JS 代码,使用起来特别方便. 在 Qt 中使用 C++ 开发底层,QtQuick 用来加载.处理图像,然后使用 Qt 提供的接口 ...

  6. 在 C++ 中与 QML 对象交互

    简述 所有的 QML 对象类型 - 无论由引擎内部实现还是由第三方源定义,都是 QObject 派生的类型.这意味着,QML 引擎可以使用 Qt 元对象系统动态实例化任何 QML 对象类型并检查创建的 ...

  7. QML基础(一)-基本元素和属性

    任何知识,都有自己的体系架构,掌握了体系架构,按图索骥的去学习的效率要远高于漫无目的的学习.这里我参照QML的知识框架和一些问题来对QML进行系统的总结.问题列表如下: 1.QML是什么? 2.为什么 ...

  8. bluemix java_Bluemix 基础:将 SQL 数据库添加到您的 Java 应用程序中

    概述 学习如何在 Bluemix 上创建一个 SQL 数据库,并将其添加到您的 Java Web 应用程序中.探索一个数据驱动.动态生成的网络商店,该商店会根据当前库存水平来改变外观.使用基于 Web ...

  9. c语言规定 程序中各函数之间().,C语言基础笔试题

    1.C语言程序的基本单位是____ A) 程序行 B) 语句 C) 函数 D) 字符.C.1 2.C语言程序的三种基本结构是____ A.顺序结构,选择结构,循环结构 B.递归结构,循环结构,转移结构 ...

最新文章

  1. 将数据库表中数据转为XML
  2. 精确微妙计时minicom 源码节选
  3. Linux 3D 编程学习总结
  4. python引入redis_十六大Python面试题!看完面试官给了我40K的薪资
  5. 基于物联网的新型智能家居控制系统设计
  6. Android 进度条改变图片透明度
  7. 尽量少一点甲方思维,也尽量少一点弱势方思维
  8. 算法基础:BFS和DFS的直观解释
  9. 机器学习实战 - 读书笔记(05) - Logistic回归
  10. 大智慧炒股软件下载|选股软件
  11. 什么是Mbps、Mbs、MBs
  12. 图像处理——人脸情绪识别(python卷积神经网络)
  13. 输入一个年份和一个月份,输出该年此月天数;知道日期,计算该日是本年的第几天(c语言)
  14. htmlcss,Hbuilder入门小项目——我的淘宝,相似
  15. 投标书如何写?(转)
  16. android逆向分析so,Android逆向——so反编译分析由浅入深(回帖奖励)
  17. 负载均衡服务器性能评估,性能测试:pgpool做负载均衡的性能评估
  18. QT 利用QPixmap复制图片
  19. message提示框的三种显示方式
  20. 我前妻的故事:一个初中肄业生从月…

热门文章

  1. 主进程退出后子进程还会存在吗?_【干货】Linux进程模型 全解
  2. markdown 菜单 折叠_疑似三星Z Fold 3折叠屏手机专利公布 带有S pen手写笔存储槽_手机行情...
  3. java 中 statent,【行为型模式】状态模式(state)之23种java设计模式
  4. vsflexgrid单元格换行后自动使用行高_Excel表格不会换行?10个超实用Excel小技巧,用了都说好!...
  5. java oracle管理系统_哔站播放量高达三百万的Java视频教程,如此惊人,还不来学?...
  6. Xilinx IOdelay--Virtex-5介绍
  7. 世界科学技术通史_全球科技通史
  8. python查看函数参数快捷键_Python基础知识—快捷键
  9. unity应用开发实战案例_Unity游戏案例开发大全 (吴亚峰等著) 完整pdf高清版[31MB]...
  10. 商业逻辑12讲之管理沟通的逻辑