当前位置: 首页 > 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://www.xdnf.cn/news/1161055.html

相关文章:

  • (9)机器学习小白入门 YOLOv:YOLOv8-cls 技术解析与代码实现
  • uni-app 开发小程序项目中实现前端图片压缩,实现方式
  • Java基础面试题
  • Laravel 后台登录 403 Forbidden 错误深度解决方案-优雅草卓伊凡|泡泡龙
  • 芯谷科技--固定电压基准双运算放大器D4310
  • kafka 日志索引 AbstractIndex
  • 智慧场景:定制开发开源AI智能名片S2B2C商城小程序赋能零售新体验
  • Web开发:ABP框架12——中间件Middleware的创建和使用
  • delphi disqlite3 操作sqlite
  • 通信刚需小能手,devicenet转PROFINET网关兼容物流分拣自动化
  • 【Elasticsearch】IndexModule
  • 【Elasticsearch】BM25的discount_overlaps参数
  • SVM(Support Vector Machine)从入门到精通
  • [Python] -项目实战10- 用 Python 自动化批量重命名文件
  • odoo-059 xml中字段上写 domain 和 filter_domain 什么区别
  • 第三章自定义检视面板_创建自定义编辑器类_如何自定义预览窗口(本章进度5/9)
  • Ubuntu 22.04 安装 Jdk 8和 Tomcat (安装包形式)
  • 基于python django的BOSS直聘网站计算机岗位数据分析与可视化系统,包括薪酬预测及岗位推荐,推荐算法为融合算法
  • Sklearn 机器学习 IRIS数据 理解分类报告
  • Nginx IP授权页面实现步骤
  • 分布在内侧内嗅皮层(MEC)的带状细胞对NLP中的深层语义分析有什么积极的影响和启示
  • Zetane:让深度学习不再抽象,一键3D可视化
  • CFD总压边界条件的理解与开发处理
  • 深入解析 Linux 硬链接与软链接:原理、区别及应用场景
  • 用户虚拟地址空间布局架构
  • C语言:20250721笔记
  • 日历类生辰八字九九三伏入梅出梅算法
  • 【用unity实现100个游戏之34】使用环状(车轮)碰撞器(Wheel Collider)从零实现一个汽车车辆物理控制系统,实现一个赛车游戏
  • PHP反序列化漏洞详解
  • 悬镜安全将受邀参加2025开放原子开源生态大会