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

【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 #注意这里
)
...

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

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

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

效果:

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

解析:

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

之前我以为普通函数也可以,实测不行,必须是槽函数。

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

先记录到这里,本文完。


文章转载自:
http://trite .sxnf.com.cn
http://semiprecious .sxnf.com.cn
http://phenomenal .sxnf.com.cn
http://laddic .sxnf.com.cn
http://psychanalysis .sxnf.com.cn
http://madeira .sxnf.com.cn
http://delightsome .sxnf.com.cn
http://teleobjective .sxnf.com.cn
http://pasteurise .sxnf.com.cn
http://sibilance .sxnf.com.cn
http://riskiness .sxnf.com.cn
http://dystopian .sxnf.com.cn
http://rco .sxnf.com.cn
http://muddledom .sxnf.com.cn
http://galvanotaxis .sxnf.com.cn
http://titivate .sxnf.com.cn
http://recreate .sxnf.com.cn
http://penicillium .sxnf.com.cn
http://decisive .sxnf.com.cn
http://saltatorial .sxnf.com.cn
http://heres .sxnf.com.cn
http://bayman .sxnf.com.cn
http://uptore .sxnf.com.cn
http://posthouse .sxnf.com.cn
http://gmat .sxnf.com.cn
http://semidesert .sxnf.com.cn
http://turfite .sxnf.com.cn
http://meadowlark .sxnf.com.cn
http://dexamethasone .sxnf.com.cn
http://medication .sxnf.com.cn
http://www.dtcms.com/a/290139.html

相关文章:

  • 【C++11】哈希表与无序容器:从概念到应用
  • ElasticSearch:不停机更新索引类型(未验证)
  • git switch
  • (LeetCode 面试经典 150 题) 219. 存在重复元素 II (哈希表)
  • taro微信小程序的tsconfig.json文件说明
  • 自动化与安全 - 将 Terraform 集成到 CI/CD
  • 编译支持cuda硬件加速的ffmpeg
  • 数据库和数据仓库的区别
  • day27 力扣332.重新安排行程 力扣51. N皇后 力扣37. 解数独 力扣455.分发饼干 力扣376. 摆动序列 力扣53. 最大子序和
  • 云原生周刊:K8s 中的后量子密码学
  • OpenCV计算机视觉实战(16)——图像分割技术
  • 微服务的编程测评系统-身份认证-管理员登录前端
  • LeetCode|Day21|204. 计数质数|Python刷题笔记
  • 【黑马SpringCloud微服务开发与实战】(四)微服务02
  • 随笔20250721 PostgreSQL实体类生成器
  • 【TVM 教程】TVM 代码库实例讲解
  • Spring AI 集成阿里云百炼与 RAG 知识库,实现专属智能助手(框架思路)
  • 若依前后端部署
  • Linux进程核心机制:状态、优先级与上下文切换详解
  • 基于Python flask的电影数据分析及可视化系统的设计与实现,可视化内容很丰富
  • 信息整合注意力IIA,通过双方向注意力机制重构空间位置信息,动态增强目标关键特征并抑制噪声
  • 文本数据分析
  • 数据分析的尽头是什么?是洞察,而非数字!
  • Car Kit重构车机开发体验,让车载应用开发驶入快车道
  • 分布式定时任务系列13:死循环是任务触发的银弹?
  • Mac上安装Claude Code的步骤
  • Python Locust库详解:从入门到分布式压力测试实战
  • 【web自动化】-5- fixture集中管理和项目重构
  • 2025最新版PyCharm for Mac统一版安装使用指南
  • Q10900H6迷你电脑:集成双10G+四2.5G网口,支持多系统网络部署