QML基础——在C++程序中使用QML

QML简介 QML与Qt程序 Qt Declarative UI运行环境 QML文档通过QML运行环境载入并运行. 包含Declarative UI引擎和内置的QML元素, 插件模块, 还提供了访问第三方的QML元素与模块. QML与Qt 单纯使用QML可以不了解Qt, 但是如果想设计一个数据逻辑和UI分开的结构, 则需要用到Qt; QML可直接访问的Qt类: 阅读详情

本文翻译自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_OBJECT
 public:
     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中访问。
使用QML进行界面开发 1、概述     ESM6802是英创公司推出的基于Freescale i.MX6DL双核处理器(ARM Cortex-A9,主频1GHz)的高性能工控主板,imx6dl内部带有硬件3D、2D图像处理模块,能够对图像界面绘制进行硬件加速,使得应用程序显示更加快速流畅。ESM6802支持Qt 5.8版本,支持使用QML进行界面开发,而且能够利用硬件图像加速处理模块优化QML构建的图像界面的渲染。... 阅读详情

相关推荐

根据文档记录Qml的console API各个不同的功能

在调试应用程序时,输出一些log是常用的一种方法。QML提供了log输出的多个api,常用的是console.log(),直接输出参数内容。 console.log(): 与console.log()类似的还有console.debug()/info()/warn()/error(),用法如下 functionconsole_log(){ consol...

波风水门 1438

在C++程序中使用QML

本文翻译自Using QML in C++ Applications。欢迎大家编辑、修改此文章。 QML API有三个主要成员——QDeclarativeEngine,QDeclarativeComponent和QDeclarativeContext。 QDeclarativeEngine提供了QML的运行环境。QDeclarativeComponent封装了...

feipigwang 371

QML基础类型之bool

二进制true / false值。 布尔类型是指二进制的true / false值。 例: Item { focus: true clip: false }

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1199

QML官方系列教程——Qt QML

附网址:http://qt-project.org/doc/qt-5/qtqml-index.html Qt QML Qt QML模块为基于QML language开发应用程序和库提供了语言和基础建设。它定义并实现了QML的语法和基础框架,并提供API使得应用程序开发者可以使用定制的类型扩展QML,或者将QML与JavaScript、C++集成起来。Qt QML模块同时提供了一个QML

Cloud_Castle的博客 3万+

1.qml-创建第一个程序

1.qt quick和qml 在Qt 5中,Qt Quick被描述为QML类库,Qt Quick是QML的一个数据类型和功能的标准库,包含了可视化类型、交互类型、动画、模型和视图、粒子特效和渲染特效等。在QML应用程序中,可以通过一个简单的import语句来使用该模块提供的所有功能。而且Qt 5发布了新的QtQuick 2.x版本, 通过 OpenGL(ES)2.0 抽象层,对绘图刷新方面大大提...

抵抗时间扭曲,坚持做一件有意义的事 6233

【Qt QML】QML初探

使用QtQuick模块,设计人员和开发人员可以轻松地在QML中构建流畅的动画用户界面,并可以选择将这些用户界面连接到任何后端C++库。它定义并实现了语言和引擎基础结构,并提供了一个API,使应用程序开发人员能够使用自定义类型扩展QML语言,并将QML代码与JavaScript和C++集成在一起。Qt QML模块提供QML引擎和语言基础结构,Qt Quick模块提供用QML创建用户界面所需的所有基本类型。它包括视觉类型,交互类型,动画,模型和视图,粒子效果和着色器效果。

wangyi463295828的博客 1910

Qt QML

Qt QML The Qt QML module provides a framework for developing applications and libraries with theQML language. It defines and implements the language and engine infrastructure, and provides an API to enable application developers to extend the QML languag.

aggs1990的专栏 459

python画弗里德曼(Friedman) 检验和秩和检验(Nemenyi)检验图

python画弗里德曼(Friedman) 检验和秩和检验(Nemenyi)检验图 画好后效果图 实现代码如下 import matplotlib.pyplot as plt #算法平均排名 _alg_=[1.405,2.643,2.786,2.167] y=[1,2,3,4]#alg1,alg2,alg3,alg4 通过Nemenyi测试计算得到的临界值CD CD=1.024 h_CD=CD/2 plt.figure(figsize=(10,6)) plt.scatter(_alg_,y,s=10

大模型天花板 4464

随笔分类 - QML

 QML基础——在C++程序中使用QML 摘要: 本文翻译自Using QML in C++ Applications。欢迎大家编辑、修改此文章。QML API有三个主要成员——QDeclarativeEngine,QDeclarativeComponent和QDeclarativeContext。QDeclarativeEngine提供了QML的运行环境。QDeclarativeComp

linuxarmsummary的专栏 410

如何实现SOLIDWORKS阵列的“智能变更”?

有时,我们在设计一个零件时,零件上有一排阵列孔,同时零件有不同的长度,我们又希望可以做到零件长度改变时,这排孔可以按长度等距增减孔阵列的个数;或是零件长度加长或缩短时,这排孔保持个数不变,按零件长度增减孔距。 那具体要怎么做呢?接下来,我们一起来看看怎么用SOLIDWORKS中简单的操作来实现这两种智能的变更: 零件长度加长或缩短时,这排孔要按长度等距增减孔阵列的个数。 零件长度加长或缩短时,这排孔保持个数不变,按零件长度增减孔距。 那接下来,我们一起来看看怎么用简单的操作来实现这两种智能的

SOLIDWORKS艾金米 2077

Halcon 算子 select_shape

作用:借助形状特征选择区域; 参数翻译(对应以上参数顺序): 输入区域、 输出满足条件的区域、 输入参数形状特征('anisometry', 'area', 'area_holes', 'bulkiness'等)、 输入参数关系符('and', 'or')、 输入参数下限值(0.0 ≤ Min ≤ 99999.0)、 输入参数上限值(Max >= Min 并且0.0 ≤ Max ≤ 99999.0); 描述: 算子select_shape根据形状特征选择区域,对于...

奔跑的郑的博客 2万+

Qt Quick 手册

Qt Quick 简介 Qt Quick提供了一套高动态,丰富的QML元素来定制用户界面的说明性框架。Qt Quick有助于 程序开发员与界面设计员的合作为便携式设备建立流畅的用户界面,例如:移动电话、媒体播放器,机 顶盒以及上网本等。Qt Quick包含了QtDeclarative C++模块,QML并且它们全被整合到Qt Create IDE中。使用QtDeclarative C

wuqing1220的专栏 2719

74LS161/48 交通灯控制系统:30-5-20-5 时序逻辑电路 Multisim 仿真验证

本文详细解析了基于74LS161/48芯片的交通灯控制系统设计,通过Multisim仿真验证30-5-20-5时序逻辑电路。从系统架构搭建、状态机实现到波形分析,提供全流程操作指南与典型问题排查方法,助力数字电路课程设计高效完成。

weixin_26742753的博客 377

QML 应用程序开发技术总结

QML 应用程序开发技术总结

Lion Chen i 咖啡 4286

Unity雷达图效果实现

unity雷达图源码

a604263644的博客 1026

Xilinx FPGA 10G Ethernet Subsystem example

The 10G Ethernet subsystem provides 10 Gb/s Ethernet MAC, Physical Coding Sublayer(PCS) and Physical Medium Attachment (PMA) transmit and receive functionality over anAXI4-Stream interface.

青城扬沙的博客 2379

《OpenCV3和Qt5计算机视觉应用开发》学习笔记第12章

本章主要介绍Qt Quick应用程序,qml与c++混合编程,同时集成opencv.包含以下主题: ❑ QML介绍 ❑ Qt Quick应用程序工程项目的结构 ❑ 创建Qt Quick Controls 2应用程序 ❑ Qt Quick Designer的使用 ❑ C++和QML集成 ❑ 在Android和iOS上运行Qt和OpenCV应用程序

chenyijun的专栏 1851

2026.1.9:最新VSCode集成claude插件完美解决方案,跳过登录界面,使用国内Kimi K2进行计费

本文介绍了如何安装配置Claude插件并连接Kimi K2 API的详细步骤:1)搜索安装Claude插件;2)进入设置关闭登录提示;3)在settings.json中添加API配置,包括ANTHROPIC_AUTH_TOKEN(需替换为Kimi API Key)和ANTHROPIC_BASE_URL;4)通过Kimi官网获取API Key。完成配置后即可正常使用该插件。文中配有完整的操作截图指引。

拥抱具身智能,昇腾Ascend C 8719

Qt Quick

Qt Quick提供了一套高动态,丰富的QML元素来定制用户界面的说明性框架。Qt Quick有助于 程序开发员与界面设计员的合作为便携式设备建立流畅的用户界面,例如:移动电话、媒体播放器,机 顶盒以及上网本等。Qt Quick包含了QtDeclarative C++模块,QML并且它们全被整合到Qt Create IDE中。使用QtDeclarative C++模块可以从你的QT 应

UbuntuKylin的专栏 4749

【C语言笔记初级篇】第一章:C语言快速入门及注意事项

(1)第一个C语言程序 A:利用vs2010写C语言程序 1:按以下步骤新建工程 2:添加源文件,“.c”文件 B:第一个C语言代码 1:以下是基本的C语言程序 2:由于没有设置连接器,所以打印结果没有显示,按照如下步骤链接控制台 (2)数据类型 A:基本数据类型及占用字节 B:一些概念的梳理 概念一:关于计算机的单位 位(bit):计算机通过电路的开关和闭合处理信息,电路通...

快乐江湖的博客 3737

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: QML基础——QML国际化(中文示例)
下一篇: 输入输出重定向
獠
獠
博客等级 码龄16年 43粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值