【qml-3】qml与c++交互第二次尝试(类型方式)

背景:

【qml-1】qml与c++交互第一次尝试(实例方式)

【qml-2】尝试一个有模式的qml弹窗-CSDN博客

 【qml-3】qml与c++交互第二次尝试(类型方式)

还是qml学习笔记。

这次搁置太久了。其实不太会,还是以教程为主,但讲课那哥们也是以尝试为主,只是人家经验多。这里吐槽一下,qml目前还是差太多。

官方手册都啥也不是,远不如widget完善好用。版本差异有些挺大,比如学了5再用6,有些真不一样。我干脆从最新的6开始搞,因为5早晚淘汰。

写代码时有些属性明明能用,但就是报错说非法,你得按住ctrl转到类型定义,还不能跳转到头文件,弹窗报错但能复制那个头文件的名,然后去文件系统qt安装目录里找到它再参考,发现里面有这个属性可以用。

先吐槽这些,也许是自己太笨。

回顾:

之前写过实例方式的qml和c++交互。

【qml-1】qml与c++交互第一次尝试(实例方式)

亦即,在c++里直接把类型实例化,把对象指针注册到qml上下文,然后qml直接调用它。

这种方式倒是直截了当,但是从qml里看有些晦涩,冷不丁出来个对象名,拿来就用。

个人感觉这种方式还可以,适合规模小的项目,简单高效。

类型方式:

本次记录的是类型方式,亦即把c++里写好的类,不实例化,而是把类型注册给qml,就像它自己的Button、Item一样,用的时候使用“{}”给它实例化。这么说起来好像更合适一些。那就上demo。

quick项目说明:

这里要插入一段,我觉得按照官方态度,应该是让咱们用Design Studio(DS)做ui,导出到c++的quick项目再混合编程。

这个该死的DS熟悉起来别具一格,等有时间再整理。这里主要说quick项目。

如上图,两种类型,图上选中的是分类类型,构建后qml文件会复制到build目录,发布时跟着exe一起,前后端分离。好处是可以随时改qml不用编译exe,不好就是所谓不安全。

compat那个是把qml放到qrc资源文件,它就一起编译进exe发布,所谓更安全。

隐约记着其实web也有这种概念,以前做c#全栈,我们都是上传aspx,改着方便。

这次demo我选的分离方式,无所谓,改一下很简单。

demo:

如上所说我选的不带compat的quick项目,一路下一步就行,它默认是cmake方式构建。

如上图,我已经添加了一个MyClass类。代码如下:

#ifndef MYCLASS_H
#define MYCLASS_H#include <QObject>
#include <QQmlEngine>
#include <QDebug>class MyClass : public QObject
{Q_OBJECTQML_ELEMENT
public:explicit MyClass(QObject *parent = nullptr);public slots:QString onFunc(){qDebug() << "slot in cpp";return "cpp value";}void onFromQml_GetValue(){qDebug() << "onFromQml_GetValue";emit sigToQml_SendValue("cpp_value");}signals:void sigToQml_SendValue(QString);
};#endif // MYCLASS_H
#include "myclass.h"MyClass::MyClass(QObject *parent): QObject{parent}
{qDebug() << "Class is created in cpp.";
}

已经尽量简单了。主要为了验证一些事。

上面QString onFunc()这个槽函数加了返回值。各位应该记得,qt手册里讲过,connect的队列模式下信号是拿不到返回值的,因为是异步。只有direct和阻塞队列方式可以,也容易理解。这里不深究qt手册了,您可以自己看,要是我记错了咱再讨论。我这里就是为了验证qml和c++之间是个啥情况。

onFromQml_GetValue槽函数就再正常不过了,不多解释。就是让它接受qml发来的信号,再把“返回值”发给qml。我就是想实现qml调用c++,比如查询。

再看qml代码:

import QtQuick
import QtQuick.Controls
import cpp.MyClassWindow {id: rootwidth: 640height: 480visible: truetitle: qsTr("Hello World")//qml查询信号signal sigToCpp_GetValueonSigToCpp_GetValue: {myclass.onFromQml_GetValue();}//c++返回信号Connections {target: myclass//以下两种方式都可以,非要共存那就下面的传统方式优先,我试出来的。//Connections里面,function方式推荐,官方已经不推荐传统方式了。        function onSigToQml_SendValue(s) {btn.text = s;print("-----" + s);}// onSigToQml_SendValue: (s) => { root.title = s; }}//C++实例化MyClass {id: myclass}Button {id: btnwidth:  100height: 40text: "press me"onClicked: {// text = myclass.onFunc();//这是可以的sigToCpp_GetValue();//发送qml信号}}
}

CMakeLists.txt

...
qt_add_executable(appuntitledmain.cpp# myclass.h myclass.cpp #注意这里
)qt_add_qml_module(appuntitledURI cpp.MyClass #注意这里VERSION 1.0QML_FILESMain.qmlSOURCES myclass.h myclass.cpp #注意这里
)
...

对于CMakeList.txt的内容,说明一下。在qml分离方式的项目中添加类,它会在CMakeLists.txt中把头文件和源文件加到qt_add_qml_module函数中,在qml资源方式的项目中,它会加到qt_add_executable函数中。亲测效果没影响,但是个人感觉加在qt_add_executable中更合适。这算一个讨论点。因为目前我没试出来区别。

注意,cmake里设置的URI是qml里import时用的模块,同时对应build目录中那个扩展名是qmltypes的文件路径。至于自己定义的c++类名,和这个没有直接关系。如果有多个c++类要为qml服务,可以都加到某个模块中。就像QtQuick.Controls一样,里面有好多类。

我之前以为,C++里只要写了那个QML_ELEMENT宏就可以自动实现了,但不幸还得改cmake文件,这个URI是个地址,对应build目录里的情况。

之前默认可不是这样的,qt会默认一个untitile,你把它改成自己想要的就行了。当然对应main函数也要改。

因为项目选择的是分离模式,理论上qml是不参与编译,而是单独的文件,所以这里写的路径其实对应build目录里的文件路径,发布时一并复制给目标机即可。

(我实测结果大相径庭!qrc模式的exe编译出来很小,一个文件包括所有,感觉很快很好用。分离模式exe很大,编译很慢,也并不是所有qml文件复制过去修改就生效,我试出来的也就第一个加载的qml可以,其余被调用的qml修改不能反应到界面,跟想象差距太大,个人感觉非常难用。希望用qml做过大项目的朋友指点。或者以后总结出经验再专门写笔记。)

效果:

没问题的,就是点击按钮,由qml向c++发送请求,c++返回数据。

解析:

其实最直接简单的方式就是直接调c++的槽函数就行了,可以带返回值,目前感觉最方便。

之前我以为普通函数也可以,实测不行,必须是槽函数。(后面有补充Q_INVOKABLE)

非要发信号走个流程就是上面那样,跟第一篇博客(实例方式)一样道理。就是实例化的时机不一样。

问题:

无论是哪种方式的项目,看教程以及我亲测都会有个问题。每次做完了运行不影响,但qml文件里总有警告,以下三步操作后警告会消失,不一定第几步有效。

1、先运行一下,让它生成build目录,寻址需要。

2、关闭项目,重新打开项目。

3、关闭creator,重新打开。

到这里忍不住还是要吐槽,这可不是我一个人的问题,教程视频里也是如此。还是不完善。您说呢?

补充:

上面说直接调用c++普通函数不行,其实是如果是普通函数,声明时需要在前面加一个宏Q_INVOKABLE。具体看手册吧,这个宏的意义就是让函数可以被元对象系统调用。熟悉qt信号槽的朋友到这里应该明白原因了。qt推崇的松散耦合就是信号槽,元对象系统实现的,qml这种前后端分离的东西显然也是基于元对象的信号槽。这就是为什么直接调用普通函数不可以,而是要加上这个宏。

先记录到这里,本文完。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90399.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90399.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

输电线路观冰精灵在线监测装置:科技赋能电网安全的新利器

一、技术架构与工作原理输电线路观冰精灵在线监测装置&#xff08;简称“观冰精灵”&#xff09;是一款集成多源感知、智能分析、远程通信于一体的专业化覆冰监测设备。其核心功能通过以下技术路径实现&#xff1a;1. 数据采集模块视觉识别系统&#xff1a;搭载工业级夜视摄像机…

Ubuntu22 上,用C++ gSoap 创建一个简单的webservice

创建calc.h// calc.h // gSOAP 服务定义 int ns__add(double a, double b, double &result); int ns__subtract(double a, double b, double &result);创建my_server.cpp#include "soapService.h" #include "ns.nsmap" class MyService : public S…

Java(LinkedList和ArrayList底层分析)

LinkedList全面说明:LinkedList底层操作机制:LinkedList的方法:add():增加节点对象remove():删除一个节点对象(默认删除第一个节点对象)set():修改一个节点对象get():得到一个节点对象LinkedList的遍历:增强for循环迭代器普通for循化LinkedList的源码解读:增加源码:1. LinkedLi…

开源项目XBuilder的user逻辑

stores \ userquery-keys.ts 统一管理Vue Query&#xff08;TanStack Query的Vue适配版本&#xff09;缓存键&#xff0c;在下面的文件中复用index.ts 入口文件&#xff0c;统一用户信息查询signed-in.ts 登录状态管理、认证逻辑在用户登录后&#xff0c;系统颁发一个令牌&…

第十五章 SEO的简单免费工具

SEO的基础工具和检测 前文中主要是讲一些SEO的网站基本功&#xff0c;而在这一章那&#xff0c;会讲到一些非常基本的工具&#xff0c;主要是关于&#xff1a;网站的流量、停留时长、关键词密度、内容、以及Google的站长工具。 Google Search Console Google Search Console这是…

SSL 证书与 HTTPS 的关系:一文理清核心关联

HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;和 SSL 证书&#xff08;Secure Sockets Layer Certificate&#xff09;是网络安全的两大基石&#xff0c;它们共同保障了互联网通信的安全性和可信度。以下从定义、功能、关系及实际应用层面进行解析&#xf…

使用Jmeter参数化实现接口自动化测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 本文记录如何使用Jmeter参数化&#xff08;csv)实现接口自动化——测试Token不同入参情况下&#xff0c;接口请求能够返回正确的结果1. 首先需要使用Jmeter获取一个…

X-plore File Manager v4.34.02 修改版:安卓设备上的全能文件管理器

在使用安卓设备时&#xff0c;文件管理是日常操作中不可或缺的一部分。X-plore File Manager 作为一款功能强大的文件管理器&#xff0c;凭借其丰富的功能和便捷的操作&#xff0c;成为安卓用户管理文件的首选工具之一。最新版 v4.34.02 修改版更是解锁了更多高级功能&#xff…

React+threejs两种3D多场景渲染方案

在现代 Web 开发中&#xff0c;3D 可视化需求日益增长&#xff0c;特别是在 React 生态系统中实现多 3D 场景的展示与交互。本文通过对比两种实现方案&#xff0c;探讨 React 中构建多 3D 场景的最佳实践&#xff0c;分析它们的技术特点、性能表现和适用场景。方案一&#xff1…

React性能优化终极指南:memo、useCallback、useMemo全解析

掌握 React.memo、useCallback、useMemo 的正确使用姿势&#xff0c;让你的 React 应用性能飞起来&#xff01; &#x1f3af; React.memo 作用 React.memo 是一个高阶组件&#xff0c;用于函数组件&#xff0c;通过浅比较 props 的变化来决定是否重新渲染。如果 props 没有变…

借助 VR 消防技术开展应急演练,检验完善应急预案​

应急演练是企业应对火灾事故的重要手段&#xff0c;而 VR 消防技术的应用&#xff0c;为应急演练带来了全新的体验和更高的效率。VR 消防技术通过虚拟现实技术模拟逼真的火灾场景&#xff0c;让参与者能够身临其境地感受火灾发生时的紧张氛围。某知名物流企业&#xff0c;仓库众…

【电赛学习笔记】MaxiCAM 项目实践——二维云台追踪指定目标

前言 本文是对视觉模块MaixCam实现二维云台人脸跟踪_哔哩哔哩_bilibili大佬的项目实践整理与拓展&#xff0c;侵权即删。 单路舵机基本控制 #导入必要模块 from maix import pwm, time , pinmap#定义全局变量&#xff0c;设初值 SERVO_FREQ 50 #主频 SERVO_MIN_DUT…

深入解析 ArkUI 触摸事件机制:从点击到滑动的开发全流程

摘要 随着 HarmonyOS NEXT 的不断发展&#xff0c;ArkUI 逐渐成为主流的 UI 构建方式。而用户交互在任何应用中都是基础而又关键的一环&#xff0c;如何利用 ArkUI 提供的触摸事件机制&#xff0c;如 onTouch、onClick、onSwipe 等&#xff0c;来实现自然、顺滑、用户友好的交互…

Tailwind CSS 自定义工具类与主题配置指南

一、自定义工具类配置在 src/tailwind.css 文件中&#xff0c;我们可以通过 layer utilities 指令添加自定义工具类&#xff1a;tailwind base; tailwind components; tailwind utilities;layer utilities {/* 自定义工具 上下浮动效果 */.animate-floatY {animation: floatY 3…

【代码随想录二刷|704.二分查找、27.移除元素、977.有序数组的平方】

704.二分查找 题目链接&#xff1a;704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int search(vector<int>& nums, int target) {//不用二分查找&#xff0c;直接求// for(int i0;i<nums.size();i){// if(nums[i]target)…

基于Vue的工业设备大屏可视化模板(含设备地图分布+宣传模块+报表展示+三维模型加载预览)

场景 为实现工业设备可视化大屏需求&#xff0c;可实现基于地图的设备数据管理&#xff0c;点击具体设备可进行详细介绍和三维模型展示。 可播放宣传视频&#xff0c;可展示PM数据报表等数据&#xff0c;可接受报警数据提醒、统计等数据。 基于现有开源平台框架进行二次改造…

堆(Heap)优先级队列(Priority Queue)

一、堆的概念堆&#xff08;Heap&#xff09;是一种特殊的基于树的数据结构&#xff0c;通常分为最大堆和最小堆两种类型。它满足堆属性&#xff1a;对于最大堆&#xff0c;父节点的值总是大于或等于其子节点的值&#xff1b;而对于最小堆&#xff0c;父节点的值总是小于或等于…

踩坑记录:因版本不匹配导致 Boost 1.85 编译失败的完整解决过程

踩坑记录&#xff1a;因版本不匹配导致 Boost 1.85 编译失败的完整解决过程 转载请注明出处&#xff0c;欢迎评论区交流。 背景 最近在 Windows 11 VS2022 环境下尝试用 b2 编译 Boost 1.85.0&#xff0c;结果一路踩坑&#xff0c;最后发现罪魁祸首是 Boost.Build 自带的 msv…

InfluxDB Line Protocol 协议深度剖析(二)

四、Line Protocol 写入操作与实践&#xff08;一&#xff09;HTTP API 写入使用 HTTP API 是通过 Line Protocol 写入数据到 InfluxDB 的常用方式。InfluxDB 1.x&#xff1a;请求方式为 POST&#xff0c;URL 格式为 “http://host:port/write?dbdatabase_name”。其中&#x…

负载均衡:提升业务性能的关键技术

一.负载均衡&#xff08;3.6 &#xff09;1.1.什么是负载均衡&#xff1a;负载均衡&#xff1a;Load Balance&#xff0c;简称LB&#xff0c;是一种服务或基于硬件设备等实现的高可用反向代理技术&#xff0c;负载均 衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个…