当前位置: 首页 > news >正文

QML与C++通信

一、QML中如何使用C++的类和对象

前提条件:
1.从 QObject 或 QObject 的派生类继承
2.使用 Q_OBJECT 宏
这两个条件是为了让一个类能够进入 Qt 强大的元对象系统(meta-object system)中,只有使用元对象系统,一个类的某些方法或属性才可能通过字符串形式的名字来调用,才具有了在 QML 中访问的基础条件。
一旦导出了一个类,在 QML 中就必然要访问该类的实例的属性或方法来达到某种目的,而具有什么特征的属性或方法才可以被 QML 访问呢?

信号和槽(针对C++中类的函数而言)
class ColorMaker : public QObject
{Q_OBJECTpublic:ColorMaker(QObject *parent = 0);~ColorMaker();signals:void colorChanged(const QColor & color);void currentTime(const QString &strTime);public slots:void start();void stop();};

我们定义了 start() / stop() 两个槽, colorChanged() / currentTime() 两个信号,都可以在 QML 中通过对象的方法直接使用,例如:

ColorMaker{id:colormaker
}
colormaker.start();或者colormaker.colorChanged(color);
使用Q_INVOKABLE 宏修饰的普通函数(针对C++中类的函数而言)

在定义一个类的成员函数时使用 Q_INVOKABLE 宏来修饰,使用 Q_INVOKABLE 将某个方法注册到元对象系统中,就可以让该方法被元对象系统调用。这个宏必须放在返回类型前面。

class ColorMaker : public QObject
{Q_OBJECTpublic:ColorMaker(QObject *parent = 0);~ColorMaker();Q_INVOKABLE GenerateAlgorithm algorithm() const;Q_INVOKABLE void setAlgorithm(GenerateAlgorithm algorithm);signals:void colorChanged(const QColor & color);void currentTime(const QString &strTime);public slots:void start();void stop();
};

algorithm()和setAlgorithm(GenerateAlgorithm algorithm)都可以在在 QML 中通过对象的方法直接使用,例如:

ColorMaker{id:colormaker
}
colormaker.algorithm();
使用Q_ENUMS 宏修饰的枚举类型(针对C++中类的枚举类型而言)
class ColorMaker : public QObject
{Q_OBJECTQ_ENUMS(GenerateAlgorithm)
public:ColorMaker(QObject *parent = 0);~ColorMaker();enum GenerateAlgorithm{RandomRGB,RandomRed,RandomGreen,RandomBlue,LinearIncrease};Q_INVOKABLE GenerateAlgorithm algorithm() const;Q_INVOKABLE void setAlgorithm(GenerateAlgorithm algorithm);signals:void colorChanged(const QColor & color);void currentTime(const QString &strTime);public slots:void start();void stop();
};

QML中可通过ColorMaker.LinearIncrease直接使用。

使用Q_PROPERTY 宏修饰的变量类型(针对C++中类的变量而言)
class QQuickText : public QQuickImplicitSizeItem
{Q_OBJECTQ_ENUMS(HAlignment)Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY fontChanged)Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)...  
public:...
};

综合运用上述方法和属性:

class ColorMaker : public QObject
{Q_OBJECTQ_ENUMS(GenerateAlgorithm)Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)Q_PROPERTY(QColor timeColor READ timeColor)
public:ColorMaker(QObject *parent = 0);~ColorMaker();enum GenerateAlgorithm{RandomRGB,RandomRed,RandomGreen,RandomBlue,LinearIncrease};QColor color() const;void setColor(const QColor & color);QColor timeColor() const;Q_INVOKABLE GenerateAlgorithm algorithm() const;Q_INVOKABLE void setAlgorithm(GenerateAlgorithm algorithm);signals:void colorChanged(const QColor & color);void currentTime(const QString &strTime);public slots:void start();void stop();protected:void timerEvent(QTimerEvent *e);private:GenerateAlgorithm m_algorithm;QColor m_currentColor;int m_nColorTimer;
};

(一)QML中使用C++中的类

方法:在 C++ 中实现一个类,注册到 QML 环境中, QML 环境中使用该类型创建对象

要注册一个 QML 类型,有多种方法可用,如 qmlRegisterSingletonType() 用来注册一个单例类型, qmlRegisterType() 注册一个非单例的类型, qmlRegisterTypeNotAvailable() 注册一个类型用来占位, qmlRegisterUncreatableType() 通常用来注册一个具有附加属性的附加类型
qmlRegisterType() 是个模板函数

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

使用qmlRegisterType 需要包含 QtQml 头文件。
先说模板参数 typename ,它就是你实现的 C++ 类的类名。
qmlRegisterType() 的第一个参数 uri ,让你指定一个唯一的包名,类似 Java 中的那种,一是用来避免名字冲突,而是可以把多个相关类聚合到一个包中方便引用。比如我们常写这个语句 “import QtQuick.Controls 1.1” ,其中的 “QtQuick.Controls” 就是包名 uri ,而 1.1 则是版本,是 versionMajor 和 versionMinor 的组合。 qmlName 则是 QML 中可以使用的类名。

#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QtQml>
#include "colorMaker.h"int main(int argc, char *argv[])
{QGuiApplication app(argc, argv);qmlRegisterType<ColorMaker>("an.qt.ColorMaker", 1, 0, "ColorMaker");QtQuick2ApplicationViewer viewer;viewer.setMainQmlFile(QStringLiteral("qml/colorMaker/main.qml"));viewer.showExpanded();return app.exec();
}

上面的代码将 ColorMaker 类注册为 QML 类 ColorMaker ,主版本为 1 ,次版本为 0 ,而我起的包名则是 an.qt.ColorMaker 。注册动作一定要放在 QML 上下文创建之前。

QML中使用此类的方法:

import an.qt.ColorMaker 1.0
Rectangle {width: 360;height: 360;ColorMaker {id: colorMaker;color: Qt.green;}
}

(二)QML中使用C++中的对象

方法:在 C++ 中构造一个对象,将这个对象设置为 QML 的上下文属性,在 QML 环境中直接使用该属性
可以把 C++ 中创建的对象作为属性传递到 QML 环境中,然后在 QML 环境中访问。
main.cpp:

 QQmlContext *context = engine.rootContext();context->setContextProperty("myobject", myobject);

还有一点要说明,因为去掉了 qmlRegisterType() 调用,所以在 main.qml 中不能再访问 ColorMaker 类了,比如你不能通过类名来引用它定义的 GenerateAlgorithm 枚举类。
此种方法QML中无需import导入,可以直接使用myobject对象访问其属性和方法,例如myobject.iValue

二、C++中使用QML中的函数

QML 对象对应的类型,原本就是 C++ 类型,比如 Image 对应 QQuickImage , Text 对应 QQuickText……但是,这些与 QML 类型对应的 C++ 类型都是私有的,你写的 C++ 代码也不能直接访问。肿么办?
Qt 最核心的一个基础特性,就是元对象系统,通过元对象系统,你可以查询 QObject 的某个派生类的类名、有哪些信号、槽、属性、可调用方法等等信息,然后也可以使用 QMetaObject::invokeMethod() 调用 QObject 的某个注册到元对象系统中的方法。而对于使用 Q_PROPERTY 定义的属性,可以使用 QObject 的 property() 方法访问属性,如果该属性定义了 WRITE 方法,还可以使用 setProperty() 修改属性。所以只要我们找到 QML 环境中的某个对象,就可以通过元对象系统来访问它的属性、信号、槽等。

 engine.load(url);auto list = engine.rootObjects();auto window = list.first();//auto name = window->objectName();//QObject* obj =  window->findChild<QObject*>("myobjects");//myobjects为某个控件的objectnameqDebug() << obj;QVariant res;QVariant arg = 15;QMetaObject::invokeMethod(obj, "func", Q_RETURN_ARG(QVariant, res),Q_ARG(QVariant,arg));qDebug() << res;return app.exec();

参考文章:http://blog.csdn.net/foruok

相关文章:

QML与C++通信

一、QML中如何使用C的类和对象 前提条件&#xff1a; 1.从 QObject 或 QObject 的派生类继承 2.使用 Q_OBJECT 宏 这两个条件是为了让一个类能够进入 Qt 强大的元对象系统&#xff08;meta-object system&#xff09;中&#xff0c;只有使用元对象系统&#xff0c;一个类的某些…...

Explain详解与索引优化最佳实践

Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈 在select语句之前增加explain关键字,MySQL会在查询前设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL 注意: 如果from中包含子查询,仍会执行该子查询,将结果…...

Spring Boot轻松整合Minio实现文件上传下载功能【建议收藏】

一、Linux 安装Minio 安装 在/root/xxkfz/soft目录下面创建文件minio文件夹&#xff0c;进入minio文件夹&#xff0c;并创建data目录&#xff1b; [rootxxkfz soft]# mkdir minio [rootxxkfz soft]# cd minio [rootxxkfz minio]# mkdir data执行如下命令进行下载 [rootxxkf…...

MySql入门教程--MySQL数据库基础操作

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …...

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:Slider)

滑动条组件&#xff0c;通常用于快速调节设置值&#xff0c;如音量调节、亮度调节等应用场景。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 无 接口 Slider(options?: SliderOption…...

第五十六回 徐宁教使钩镰枪 宋江大破连环马-飞桨图像分类套件PaddleClas初探

宋江等人学会了钩镰枪&#xff0c;大胜呼延灼。呼延灼损失了很多人马&#xff0c;不敢回京&#xff0c;一个人去青州找慕容知府。一天在路上住店&#xff0c;马被桃花山的人偷走了&#xff0c;于是到了青州&#xff0c;带领官兵去打莲花山。 莲花山的周通打不过呼延灼&#xf…...

springboot/ssm企业内部人员绩效量化管理系统Java员工绩效管理系统web

springboot/ssm企业内部人员绩效量化管理系统Java员工绩效管理系统web 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&…...

XML语言的学习记录2-XMLHttpRequest

学习笔记&#xff1a;XMLHttpRequest 特点&#xff1a; 在不重新加载页面的情况下更新网页在页面已加载后从服务器请求数据在页面已加载后从服务器接收数据在后台向服务器发送数据创建XMLHttpRequest对象 xmlhttpnew XMLHttpRequest()&#xff1b;IE5 和 IE6&#xff0c;使用 …...

力扣爆刷第95天之hot100五连刷61-65

力扣爆刷第95天之hot100五连刷61-65 文章目录 力扣爆刷第95天之hot100五连刷61-65一、131. 分割回文串二、51. N 皇后三、35. 搜索插入位置四、74. 搜索二维矩阵五、34. 在排序数组中查找元素的第一个和最后一个位置 一、131. 分割回文串 题目链接&#xff1a;https://leetcod…...

聊聊powerjob的执行机器地址

序 本文主要研究一下powerjob的执行机器地址(designatedWorkers) SaveJobInfoRequest powerjob-common/src/main/java/tech/powerjob/common/request/http/SaveJobInfoRequest.java Data public class SaveJobInfoRequest {/*** id of the job. set null to create or non-…...

Android Kotlin知识汇总(三)Kotlin 协程

Kotlin的重要优势及特点之——结构化并发 Kotlin 协程让异步代码像阻塞代码一样易于使用。协程可大幅简化后台任务管理&#xff0c;例如网络调用、本地数据访问等任务的管理。本主题介绍如何使用 Kotlin 协程解决以下问题&#xff0c;从而让您能够编写出更清晰、更简洁的应用代…...

JVM垃圾收集器-serial.parNew,parallelScavnge,serialOld,parallelOld,CMS,G1

垃圾收集器 分代模型 适用于新生代&#xff1a; serial parNew parallel Scaavenge 适用于老年代&#xff1a; CMS serial Old(msc) paraller Old 分区模型 适用于超大容量&#xff1a; G1 分代模型 serial /serial Old收集器 1.单线程收集器 2.收集时会暂停其他线程&…...

docker搭建upload-labs

Upload-labs 是一个专门设计用于学习和练习文件上传安全的开源工具。它提供了各种场景的文件上传漏洞&#xff0c;供用户通过实践来学习如何发现和利用这些漏洞&#xff0c;同时也能学习到防御措施。使用 Docker 来搭建 upload-labs 环境是一种快速、简便的方法&#xff0c;它可…...

超详细外贸单证汇总!

今天给大家汇总了外贸单证的种类与使用相关知识&#xff0c;东西齐全&#xff0c;赶紧码住&#xff01; 1、合同 CONTRACT是统称,买卖双方均可出具。如系卖方制作,可称为销售确认书,买方出具则可称为采购。 买卖双方均可出具合同。卖方出具的,可称为销售确认书(Sales Confir…...

Docker部署ChatGLM3、One API、FastGPT

创建并运行chatglm3容器 docker run --name chatglm3 -p 8000:8000 registry.cn-hangzhou.aliyuncs.com/ryyan/chatglm.cpp:chatglm3-q5_1 创建并运行one-api容器 (其中挂载路径 D:\one-api 可以选择你自己喜欢的目录) docker run --name oneapi -d -p 3000:3000 -e TZAsia…...

【Linux-网络编程】

Linux-网络编程 ■ 网络结构■ C/S结构■ B/S结构 ■ 网络模型■ OSI七层模型■ TCP/IP四层模型 ■ TCP■ TCP通信流程■ TCP三次握手■ TCP四次挥手 ■ 套接字&#xff1a;socket 主机IP 主机上的进程&#xff08;端口号&#xff09;■ TCP传输文件 ■ 网络结构 ■ C/S结构…...

win10虚拟机安装驱动教程

在虚拟机菜单栏中选择安装VMware Tools&#xff1a; 安装好后&#xff0c;在虚拟机中打开此电脑&#xff0c;双击DVD驱动器进行安装&#xff1a; 一直点击下一步&#xff1a; 安装完成&#xff1a; 此时重启虚拟机&#xff0c;发面小屏幕页面的虚拟机自动占满了全部屏幕&#x…...

SpringBoot实战项目——博客笔记项目

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、项目介绍二、项目的整体框架 2.1 数据库模块 2.2 前端模块 2.3 后端模块三、项目图片展示四、项目的实现 4.1 准备工作 4.…...

【海贼王的数据航海】排序——直接选择排序|堆排序

目录 1 -> 选择排序 1.1 -> 基本思想 1.2 -> 直接选择排序 1.2.1 -> 代码实现 1.3 -> 堆排序 1.3.1 -> 代码实现 1 -> 选择排序 1.1 -> 基本思想 每一次从待排序的数据元素中选出最小(或最大)的一个元素&#xff0c;存放在序列的起始位置&…...

Flutter 的 switch 语句补遗

我的 App 里&#xff0c;一个消息气泡变成空白了&#xff0c;非常奇怪&#xff0c;此前一直是没问题的&#xff0c;经过调试定位我发现&#xff1a; static TextSpan _buildRootSpan(BuildContext ctx, List<LinkifyElement> parts, TextStyle? style) {List<InlineS…...

5步实现图表数据提取自动化:用WebPlotDigitizer提升科研效率80%

5步实现图表数据提取自动化&#xff1a;用WebPlotDigitizer提升科研效率80% 【免费下载链接】WebPlotDigitizer Computer vision assisted tool to extract numerical data from plot images. 项目地址: https://gitcode.com/gh_mirrors/we/WebPlotDigitizer 还在为手动…...

开源轻量模型新星:Qwen1.5-0.5B-Chat部署趋势分析

开源轻量模型新星&#xff1a;Qwen1.5-0.5B-Chat部署趋势分析 1. 项目概述 Qwen1.5-0.5B-Chat是阿里通义千问开源系列中的轻量级智能对话模型&#xff0c;基于ModelScope&#xff08;魔塔社区&#xff09;生态构建。这个仅有5亿参数的模型在保持良好对话能力的同时&#xff0…...

cv_resnet18_ocr-detection保姆级教程:从安装到批量处理图片文字

cv_resnet18_ocr-detection保姆级教程&#xff1a;从安装到批量处理图片文字 1. 快速上手&#xff1a;5分钟搞定OCR文字检测 你是不是经常需要从图片里提取文字&#xff1f;比如整理扫描的文档、识别截图里的信息&#xff0c;或者处理一堆商品图片上的标签。手动打字太慢&…...

千问3.5-27B中文优化实践:提升OpenClaw指令理解准确率

千问3.5-27B中文优化实践&#xff1a;提升OpenClaw指令理解准确率 1. 为什么需要专门优化中文指令理解 上周我在用OpenClaw整理项目文档时&#xff0c;发现一个有趣现象&#xff1a;当我用英文说"organize these PDFs by date"时&#xff0c;AI能准确按日期分类文件…...

Python 闭包与装饰器

在 Python 学习中&#xff0c;闭包和装饰器是两个既关联又容易混淆的知识点&#xff0c;尤其是结合嵌套函数使用时&#xff0c;常常分不清执行逻辑。但其实只要抓住核心原理&#xff0c;再结合简单案例拆解&#xff0c;就能轻松掌握。 一、前置回顾&#xff1a;函数与局部变量的…...

SEO 实战培训班在哪里_SEO 优化师培训在哪里

SEO 实战培训班在哪里_SEO 优化师培训在哪里 在当今数字化时代&#xff0c;网站的流量和排名直接关系到企业的生存和发展。这就是为什么越来来越多的企业和个人希望掌握SEO优化技能&#xff0c;成为一名优秀的SEO优化师。SEO 实战培训班在哪里呢&#xff1f;SEO 优化师培训在哪…...

告别窗口闪烁:用BLASTSyncEngine实现Android多窗口平滑过渡的完整指南

告别窗口闪烁&#xff1a;用BLASTSyncEngine实现Android多窗口平滑过渡的完整指南 在Android多窗口交互场景中&#xff0c;开发者经常面临一个棘手问题——当用户进行分屏切换、画中画调整或任务栈重组时&#xff0c;窗口内容会出现短暂闪烁或撕裂。这种视觉瑕疵不仅影响用户体…...

基于合法无代码平台滥用的新型钓鱼攻击机理与防御体系研究

摘要 2026 年 3 月卡巴斯基实验室披露针对 Bubble.io 等正规无代码开发平台的恶意滥用钓鱼攻击&#xff0c;攻击者依托平台高信誉域名、SSL 证书与可视化开发能力&#xff0c;快速生成高仿真钓鱼页面&#xff0c;绕过传统邮件网关与终端检测&#xff0c;实现账号凭证、多因素认…...

2026年最好的AI创业机会,就藏在你压根看不上的角落里

还在焦虑AI会替代你&#xff1f;抢你饭碗&#xff1f;你根本不知道&#xff0c;现在有一群人&#xff0c;正在用AI给自己“印钞票”他们不是搞什么ChatGPT插件&#xff0c;也不是训练大模型&#xff0c;他们就盯着那些看着不起眼&#xff0c;甚至你压根看不上的小事。利用这些小…...

Verilog有限状态机实战:5分钟搞定红绿灯控制器(附完整代码)

Verilog有限状态机实战&#xff1a;从红绿灯控制器掌握FPGA设计精髓 红绿灯控制器是数字电路设计的经典案例&#xff0c;也是学习Verilog有限状态机&#xff08;FSM&#xff09;的最佳切入点。作为FPGA初学者&#xff0c;你可能已经看过各种理论讲解&#xff0c;但真正动手时依…...