QML与C++混合编程

QML与C++混合编程详解 Qt集成了QML引擎和Qt元对象系统,使得QML很容易从C++中得到扩展,在一定的条件下,QML就可以访问QObject派生类的成员,例如信号、槽函数、枚举类型、属性、成员函数等。QML访问C++有两个方法:一是在Qt元对象系统中注册C++类,在QML中实例化、访问。二是在C++中实例化并设置为QML上下文属性,在QML中直接使用。与后者相比,前者可以使C++类在QML中作为一个数据类型,例如函数参数类型或属性类型,也可以使用其枚举类型、单例等,功能更强大。文章最后为大家准备了Qt资料。 阅读详情

文章参考:
https://blog.youkuaiyun.com/foruok/article/details/32698603
http://blog.51cto.com/9291927/1975383

QT项目开发过程中,画面上显示的布局以及对应的数据可能会动态变化,如果只用QML来构件简单的布局是无法满足需求的,所以会用通过C++代码来实现业务逻辑,QML负责构件UI。这里用到MVC模式的思想。
QML与C++混合编程简介
QML与C++混合编程就是使用QML高效便捷地构建UI,而C++则用来实现业务逻辑和复杂算法。

Qt Quick与QML
Qt Quick是Qt User Interface Creation Kit的缩写。
从QT框架简介中可以了解到,QML (Qt Meta-Object Language的缩写)其实是对 JavaScript 的扩展,是Qt Quick最重要的组成部分。
Qt Quick包含一个组件集合,大部分用于图形界面。同时也包含一个用于管理组件并与组件交互的C++ API——QtDeclarative模块,用于QML与C++之间的桥梁。
C++与QML的交互通过向QML注册C++对象实现,其中C++实现中,非可视化的类均为QObject的子类,可是化的类型均为QDeclarativeItem的子类,而QDeclarativeItem等同于QML的Item类。

QML 中使用 C++ 类和对象
Qt 提供了两种在 QML 环境中使用 C++ 对象的方式:

  1. 在 C++ 中实现一个类,注册到 QML 环境中, QML 环境中使用该类型创建对象;
  2. 在 C++ 中构造一个对象,将这个对象设置为 QML 的上下文属性,在 QML 环境中直接使用改属性.
    不管哪种方式,对要导出的 C++ 类都有要求,不是一个类的所有方法、变量都可以被 QML 使用,因此我们先来看看怎样让一个方法或属性可以被 QML 使用。

C++类的实现
C++类要想被QML访问,首先必须满足两个条件:

  1. 派生自QObject类或QObject类的子类;
  2. 二是使用Q_OBJECT宏。
    这两个条件跟QT信号和槽的实现一样,是为了让一个类能够进入 Qt 强大的元对象系统(meta-object system)中,只有使用元对象系统,一个类的某些方法或属性才可能通过字符串形式的名字来调用,才具有了在 QML 中访问的基础条件。

信号与槽实现
只要是信号或者槽,都可以在 QML 中访问。
信号在C++中使用时要用到emit关键字,但在QML中就是个普通的函数,用法同函数一样。

注册QML类型
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) 有两个模板函数:

template<typename T>
  int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);

  template<typename T, int metaObjectRevision>
  int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);

前一个原型一般用来注册一个新类型,而后一个可以为特定的版本注册类型。通常使用的是第一个,后面这个有兴趣可以自己详细了解。
参数含义:
typename :实现的 C++ 类的类名。
uri :让你指定一个唯一的包名,类似 Java 中的那种,一是用来避免名字冲突,而是可以把多个相关类聚合到一个包中方便引用。比如我们常写这个语句 “import QtQuick 1.0” ,其中的 “QtQuick” 就是包名 uri
versionMajor:指上述包名后面1.0中的“1”
versionMinor:指上述包名后面1.0中的“0”
qmlName : QML 中可以使用的类名。
例如:

qmlRegisterType<TestHuman >("qt.test.TestHuman", 1, 0, "TestHuman"); //只要保证在加载qml之前即可

当将C++类注册成功之后则可以在 QML 中创建 C++ 导入类型的对象了,与 QML 内建类型的使用完全一样。如下是创建一个 TestHuman 实例的代码:

import QtQuick 2.0
import qt.test.TestFlowers 1.0
Rectangle {
    width: 200;
    height: 200;
    
    TestFlowers {
        id: testflowers ;
        anchors.top: parent.top;
    }
	Button{
	id: testBtn1;
        text: qsTr("Hello World");
        anchors.top: testflowers .bottom;
        onClicked: {
                testHuman .onBtnClick();
            }
    }
}

上述qml文件可以看出C++对象可以跟其它部件使用完全一样,qml文件中通常要使用C++对象的成员属性、方法,为了能让C++的相关数据能被访问,则需要做特殊处理。

Q_PROPERTY
Q_PROPERTY 宏用来定义可通过元对象系统访问的属性,通过它定义的属性,可以在 QML 中访问、修改,也可以在属性变化时发射特定的信号。要想使用 Q_PROPERTY 宏,你的类必须是 QObject 的派生类,必须在类首使用 Q_OBJECT 宏。
下面是 Q_PROPERTY 宏的原型:

Q_PROPERTY(type name
             (READ getFunction [WRITE setFunction] |
              MEMBER memberName [(READ getFunction | WRITE setFunction)])
             [RESET resetFunction]
             [NOTIFY notifySignal]
             [REVISION int]
             [DESIGNABLE bool]
             [SCRIPTABLE bool]
             [STORED bool]
             [USER bool]
             [CONSTANT]
             [FINAL])

属性的type、name是必需的,其它是可选项,常用的有READ、WRITE、NOTIFY。属性的type可以是QVariant支持的任何类型,也可以是自定义类型,包括自定义类、列表类型、组属性等。

  • READ :如果你没有为属性指定 MEMBER 标记,则 READ 标记必不可少;声明一个读取属性的函数,该函数一般没有参数,返回定义的属性。
  • WRITE:可选配置。声明一个设定属性的函数。它指定的函数,只能有一个与属性类型匹配的参数,必须返回 void 。
    NOTIFY:可选配置。给属性关联一个信号(该信号必须是已经在类中声明过的),当属性的值发生变化时就会触发该信号。信号的参数,一般就是你定义的属性。

其它不常用的就不介绍了,感兴趣的可以查看SDK。

Q_ENUMS
如果你要导出的类定义了想在 QML 中使用枚举类型,可以使用 Q_ENUMS 宏将该枚举注册到元对象系统中。

Q_INVOKABLE
在定义一个类的成员函数时使用 Q_INVOKABLE 宏来修饰,就可以让该方法被元对象系统调用。这个宏必须放在返回类型前面。在 QML 中就可以用 O b j e c t . {Object}. Object.{method} 来访问。

代码:
C++类(.h文件):

class TestFlowers : public QObject
{
    Q_OBJECT
	Q_ENUMS(Color)
	Q_PROPERTY(Color color READ color WRITE setColor NOTIFY colorChange)
	Q_INVOKABLE void (onBtnClick)
public:
    TestFlowers (QObject *parent = 0);
    ~TestFlowers ();
	
	enum Color {
		RED,
		GREEN,
		BLUE
	};
    
};

qml:

import QtQuick 2.0
import qt.test.TestFlowers 1.0
Rectangle {
    width: 200;
    height: 200;
    
    TestFlowers {
        id: testflowers ;
        anchors.top: parent.top;
    }
	Button{
	id: testBtn1;
        text: qsTr("Hello World");
        anchors.top: testflowers .bottom;
        onClicked: {
                testflowers.onBtnClick();      //控件的点击事件,可以在类文件(.cpp)中实现业务逻辑
            }
    }
    Rectangle{
	id:background;
	width: parent.width;
	height:50;
	color:testflowers .color;        //可以直接使用C++属性值
	anchors.bottom: testBtn1.bottom;
	}
}

具体的C++类的.cpp文件就不详细写了,这里主要表达的是在qml中使用C++类的相关属性和方法。如果想在qml中使用C++类属性,则必须用特殊的宏才能使用。

注册C++ 对象为 QML 的属性
在C++应用程序加载QML对象时,可以直接嵌入一些C++数据来给QML使用,需要用到QQmlContext::setContextProperty()设置QML上下文属性,上下文属性可以是一个简单的类型,也可以是任何自定义的类对象。
以下代码在main函数中注册:

QtQuick2ApplicationViewer viewer;
viewer.rootContext()->setContextProperty("testflowers", new TestFlowers );  //这里new创建了对象,需要自己手动回收
viewer.setMainQmlFile(QStringLiteral("qml/testflowers/main.qml"));    //"qml/testflowers/main.qml"表示qml文件路径

通过上述方法注册之后。qml的使用有部分改动:

import QtQuick 2.0
// import qt.test.TestFlowers 1.0     已经注册,不需要了
Rectangle {
    width: 200;
    height: 200;
    
// 已经注册成属性了,不要了
/*    TestFlowers {
        id: testflowers ;
        anchors.top: parent.top;
    }*/
    
	Button{
	id: testBtn1;
        text: qsTr("Hello World");
        anchors.top: testflowers .bottom;
        onClicked: {
                testflowers.onBtnClick();      //控件的点击事件,可以在类文件(.cpp)中实现业务逻辑
            }
    }
    Rectangle{
	id:background;
	width: parent.width;
	height:50;
	color:testflowers .color;        //可以直接使用C++属性值
	anchors.bottom: testBtn1.bottom;
	}
}

在 C++ 中使用 QML 对象
在C++中也可以访问QML中的属性、函数和信号。QObject 类的构造函数有一个 parent 参数,可以指定一个对象的父亲, QML 中的对象其实借助这个组成了以根 item 为父的一棵对象树。
而 QObject 定义了一个属性 objectName ,这个对象名字属性,就可以用于查找对象。现在该说到查找对象的方法了: findChild() 和 findChildren() 。它们的函数原型如下:

T QObject::findChild(const QString &name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
QList<T> QObject::findChildren(const QString &name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const

用例:

QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
QList<QWidget *> widgets = parentWidget.findChildren<QWidget *>("widgetname");

在TestFlowers 类中查找testBtn1对象调用方法如下:
Button* button1 = this->findChild<Button*>(“testBtn1”);

PS:上述代码的实例没有写全,所以不要直接copy在实机上运行,上述相关方法都可以到QT SDK中找到,可以自己下载一个qt 工具,然后在里边搜索相关方法,里边都有详细介绍且非常方便(参考:QT框架简介里边的搜索方法)。

quick 2 — qml 与c++的混合编程 满足2个前提:(1)从QObjec或QObject的派生类继承;(2)使用Q_OBJECT宏;这两个条件是为了让一个类进入Qt的元对象系统,只有使用元对象系统,类的某些方法才可能通过字符串形式的名字调用,才能在QML中被访问。 阅读详情

相关推荐

Qt中C++与QML的深入比较分析

Qt中C++与QML的深入比较分析

m0_46566693的博客 1168

C++与QML混合编程

C++与QML混合编程

hurryddd 2384

QML与C++混合编程使用

C++与QML的交互是通过暴露C++对象给QML环境得以实现的: 在C++实现中,非可视化的型别均为QObject的子类,可视化的类型均为QDeclarativeItem的子类。注意:QDeclarativeItem等同于QML的Item类。 如果用户想要定义自己的型别,做法如下: 在C++中,实现派生于QObject或QDeclarativeItem的子类,它是新定义item的实体对象; 在C++中,将1中实现的新item类型注册给QML; 在QML中,导入含有1中定义的新item的模块; 在

1万+

QML与C++混合编程详解(QML与c++信号与槽的操作)

1、QML与C++为什么要混合编程 QML与C++为什么要混合编程,简单来说,就是使用QML高效便捷地构建UI,而C++则用来实现业务逻辑和复杂算法,下面介绍了两者间交互的方法与技巧。 2、QML访问C++概述 Qt集成了QML引擎和Qt元对象系统,使得QML很容易从C++中得到扩展,在一定的条件下,QML就可以访问QObject派生类的成员,例如信号、槽函数、枚举类型、属性、成员函数等。 ...

细雨纷飞~~~ 2513

QML与C++混合编程实战案例:图像处理

QML(Qt Modeling Language)是Qt框架中用于设计用户界面的声明性语言,而C++是其背后的编程语言,负责逻辑处理。混合编程技术结合了QML在UI设计上的直观性和C++在性能优化上的强大能力。本章将概述QML与C++如何协作,以及它在现代应用程序中的重要性。QML与C++的混合编程技术不仅提高了开发效率,还优化了程序性能。本章仅作为引入,为读者提供了一个整体的认识。在后续章节中,我们将深入探讨如何将QML与C++有效结合,及其在实际项目中的应用和优化。

weixin_34618526的博客 970

CMOS锁相环核心:四种鉴频鉴相器(PFD)结构深度剖析与选型指南

本文深入剖析了CMOS锁相环中四种鉴频鉴相器(PFD)的结构与性能,包括传统RS触发器型、非时钟型、预充电型和边沿触发型PFD。通过详细的电路分析、实测数据和工程案例,提供了PFD选型的实用指南,帮助工程师根据速度、功耗和精度需求选择最优方案,提升锁相环设计效率。

weixin_42530458的博客 586

QtQuick系列教程(3)——QML与C++混合编程

QML与C++混合编程一、QML与C++混合编程简介二、QML访问C++三、C++类的实现1、信号与槽实现2、枚举类型实现3、成员函数实现4、C++类的属性四、注册C++类为QML类型五、QML上下文属性设置六、C++访问QML1、C++使用QQmlComponent2、C++使用QML的属性3、C++使用QML中信号与函数七、QML与C++混合编程注意事项 一、QML与C++混合编程简介 QML...

qq_34462436的博客 1436

5G物理层基础知识

1、关于RB和RE (1) RB(Resource Block,资源块)频率上连续12个子载波,时域上一个slot(时隙,14个ofdm符号) (2) RE(Resource Element,资源单元)频率上一个子载波,及时域上一个ofdm符号 注意:协议规定,5G每个时隙(非扩展CP)的符号数为14个(扩展CP情况下每个时隙有12个符号),而LTE(非扩展CP)每个时隙的符号数为7个。 简单说:一个12X14的方格,大的整个叫一个RB,每一个小块叫一个RE。另外,一个RE可存放一个调制符号(mo.

qq_39074243的博客 2万+

Qt QML与C++混合编程

Qt QML与C++混合编程

m0_73443478的博客 2603

社工库2.0

#大题目 社工库2.0 ###环境 whoosh2.7 jieba 12306 python3.7 网上嫖来的网页模板(感谢站长之家 ###实现效果 建立的索引文件 好看的页面 更快的查找速度 ###实现过程 具体的实现过程比较简易,毕竟whoosh已经封装的很好了 第一步 建立索引并存储 schema = Schema(zhanghao=TEXT(stored=True), code=STORED, name=TEXT(stored=True, analyzer=

sdyinruichao的博客 2万+

109. SAP ABAP 应用程序中的锁机制和工作原理介绍

SAP ABAP 系统中的锁概念,是 SAP ABAP 为了保证`数据一致性`而引入的一种保护机制。 像 SAP 这种复杂的企业级应用,系统中同一时间段的同一份数据,可能会有多个 Transaction(终端用户或者 API )同时进行读写操作。为了防止出现数据不一致,SAP ABAP 引入了锁机制。 这种锁机制并非数据库服务器层面的锁,而是在 SAP ABAP 应用服务器层面上工作,加锁和解锁都由专门的 ABAP Function Module 来完成。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1466

Qt Quick 之 QML 与 C++ 混合编程详解

但它不是万能的,也有很多局限性,原来 Qt 的一些技术,比如低阶的网络编程如 QTcpSocket ,多线程,又如 XML 文档处理类库 QXmlStreamReader / QXmlStreamWriter 等等,在 QML 中要么不可用,要么用起来不方便,所以呢,很多时候我们是会基于这样的原则来混合使用 QML 和 C++: QML 构建界面, C++ 实现非界面的业务逻辑和复杂运算。一旦你在 C++ 中注册好了 QML 类型,就可以在 QML 文档中引入你注册的包,然后使用注册的类型。

宁静致远的博客 4282

iOS远程真机之WebDriverAgent 天坑记

一、WDA安装依赖报错:       这个东西神坑,我搞了一天都没找到解决方案,最后在appium讨论中发现,       解决方案是:       先定位到WebDriverAgent 所在路径$ cd /Users/XXXX/git/WebDriverAgent        然后运行:mkdir -p Resources/WebDriverAgent.bundle sh ./Scripts/b

甫式人生 7315

C++与QML混合编程技术(传递自定义数据类型)

C++与QML混合编程就是优势互补的编程策略,使用QML高效便捷地构建UI,使用C++实现业务逻辑和复杂算法。

weixin_38880029的博客 4458

多标签图像分类:标签依赖关系建模的最新论文解读与实战应用

多标签图像分类:标签依赖关系建模的最新论文解读与实战应用 ,人工智能,计算机视觉,大模型,AI,本文解读了最新相关论文,包括基于图神经网络(GCN)的ML-GCN方法,通过构建标签相关矩阵建模依赖关系;区域潜在语义依赖的RLSD模型,定位关键区域并利用RNN建模语义依赖;以及语义图表示学习的SSGRL框架,结合语义解耦与交互模块。通过实战应用,展示了基于PyTorch的ML-GCN模型实现,包括图像特征提取、标签依赖建模及训练评估流程,为多标签图像分类提供了有效解决方案。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 18万+

【Bug已解决】Codex capacity errors 自动重试与意图保留 解决方案

原始报错:Codex Desktop: capacity errors should preserve intent and auto-retry instead of handing model routing back to the user场景:向模型服务发请求时遇到容量错误(服务端繁忙 / 限流 / 容量不足),客户端不做任何重试,直接把"请求失败,请选择另一个模型或重试"的锅甩给用户,让用户手动去点。用户本来只是想完成一次任务,却被中途打断去当"调度员"。

博客 277

【QML】QML与C++混合编程

QML与C++混合编程 使用QQuickView pro文件中添加quick模块 #include<QApplication> #include<QQuickView> int main(int argc,char* argv[]){ QApplication app(argc,argv); //加载qml文件到视图 QQuickView view; view.setSource(QUrl("column.qml")); view.sho

半生瓜のblog 1567

会话管理技巧——如何优化OpenClaw的上下文理解能力(2026进阶版)

本文深入探讨了OpenClaw系统的会话管理技术,重点介绍了会话定义、生命周期管理和上下文优化策略。会话管理包含会话ID、用户信息、状态等核心要素,以及创建、维护、终止和恢复四个生命周期阶段。上下文管理通过ContextManager类实现,支持创建、更新、消息添加和变量管理等功能,并采用历史记录机制确保会话连续性。ContextOptimizer类则负责应用优化规则,通过消息和变量压缩等技术提升系统性能。这些技术共同构建了OpenClaw强大的会话管理能力,为AI助手提供了高质量的交互体验基础。

博客 489

QT QML 与C++ 混合编程

一.QML简介 从 Qt 4.7 开始,Qt 引入了一种声明式脚本语言,称为 QML(Qt Meta Language 或者 Qt Modeling Language),作为 C++ 语言的一种替代。而 Qt Quick 就是使用 QML 构建的一套类库。 QML 是一种基于 JavaScript 的声明式语言。 Qt公司推出Qt Quick技术的一部分,更好的支持触摸屏 描述性语言,非常像CSS,html,支持JavaScript,支持与C++交互 示例代...

weixin_41948631的博客 1332

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Qt/QML学习-C++与QML混合编程

Qt/QML学习-C++与QML混合编程

QT、QML 826

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: QT框架简介
下一篇: Ubuntu 中sudo update与sudo upgrade命令的作用及区别
OODeveloper
博客等级 码龄12年 43粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值