当前位置: 首页 > 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…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...