[QDS]从零开始,写第一个Qt Design Studio到程序调用的项目
前言
最近在使用Qt Design Studio进行开发,但是简中网上要不就是只搜得到Qt Designer(Qt Creator内部库),要不就只搜得到一点营销号不知道从哪里搬来的账号,鉴于Qt Design Studio是一个这么强大的软件,自然是需要来进行一下小小的实践的。
所以开了这篇文章,方便没有使用过Qt Design Studio 和 QML的开发者也可以快速上手QDS(Qt Design Studio)。在本文中,你将学会如何使用QDS开发一个简单的QML程序,与你的C++后端代码进行交流。
下文中将使用QDS指代Qt Design Studio.
下载和安装
这里先说一下这里使用的Qt版本,我现在这里使用的是Qt 6.8.0 + Qt Design Studio 4.1.1 LTS
安装Qt Design Studio我是用的Qt本身的安装包,在安装的时候它把QDS当成了一个组件,是由你个人选择来安装的
需要注意的是,这里需要选择4.1.1 LTS而不是 4.6.2,主要原因是4.1.1LTS版首先它是LTS,其次它还支持中文(虽然真正支持的中文没几个字。。。)所以这里我们选4.1.1,先上手,等之后有什么新的功能你确实一定要移动到4.6.2再移动也不迟。
第一个项目
前端准备
QDS界面如图,你可以试着创建一个项目,这里我们点Create Project…
这个界面没什么好说的改改设定就行了,然后我们点击右下角Create,这样我们就进入了我们第一个项目,也就是QDS的Hello World
点击左上角这个三角形,我们可以运行这个QML项目
我们需要知道的是,整个QDS项目的入口点其实是App.qml,而App.qml中的内容很简单,他只是简单调用了一个Screen01,这个Screen01我们先直接删掉,在这个App.qml的Window中先来写我们自己的东西。
import QtQuick 6.5
import UntitledProjectWindow {width: 500height: 200id:rootvisible: truetitle: "UntitledProject"}
这是一个带动画的小按钮项目,但是我们现在不需要这么复杂的项目,我们可以来一个最简单的项目,这个项目需要做三件事
- 能够调用后端的函数,并给定参数
- 能调用后端的函数,并接受返回值
- 能接受后端的信号
为了完成这个实践,我们需要三个控件
在视图 - 视图 - 选中2D,可以获得当前开发控件的2D展开图,同时我们在视图-视图-选中Compoents,可以获得一些预设的控件,我们先简单拖几个按钮、Text、TextEdit上去试试
搞几个控件上去
这里先说一下这个Close按钮怎么实现
我们看到这个App.qml根元素是Window,我现在给这个Window一个id:root,然后我们可以在Button的属性中添加一个onClicked信号,这个信号是点击按钮时触发的,在onClicked里面调用root.close()就可以了
Button {id: buttonx: 413y: 16width: 63height: 33text: qsTr("Close")onClicked: {root.close()}}
那么这个简单的QDS项目就算创建完成了,接下来我们要将这个QDS项目移植到C++项目去,因为我不太会用Qt Creator,我这里使用Visual Studio 2022 + Qt VSTool来演示Qt项目的结合。
现在我们就可以在QDS中导出这个项目了
它这里支持的导出方式还挺多的,我这里为了方便使用,直接以QRC的形式导出。
这里导出了之后,我们可以准备一下C++的后端了。
后端准备
这里直接创建一个空的Qt Quick项目 QDS_Totour(打错了不用在意)
这里可以直接将QDS的项目整个放在后端的文件夹内,我这里是直接将其放在了 QDS_Toutor/qml项目下,当然了也可以先创建后端项目,然后再使用QDS创建一个项目直接创建在后端项目内也是可以的
现在进入到我们的Qt项目内,将QDS_Toutor/qml下的UntitledProject.qrc(前端准备中导出的qrc文件)引入到Qt C++项目中去
可以看到此时QRC文件已经帮我们的项目组织好了整个QDS项目的依赖,现在我们只需要正常调用就可以了。我们找到QDS_Toutor的main文件,并作出对应的修改
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN) && QT_VERSION_CHECK(5, 6, 0) <= QT_VERSION && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endifQGuiApplication app(argc, argv);QQmlApplicationEngine engine;//原始导入,现在改成新的目录//engine.load(QUrl(QStringLiteral("qrc:/qt/qml/qds_toutor/main.qml")));engine.load(QUrl(QStringLiteral("qrc:/content/App.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
我们尝试运行一下,这个时候项目就可以直接运行了。
前后端连接
现在我们需要进行前后端连接。在这里进行前后端连接需要一个单独的类,用来进行前后端的信号连接,我们管这个类暂且叫它Connector,需要注意的是这需要是一个QObject的子类,虽然你从Qt Creator创建出来的类大概率是一个 QObject的子类。
我们来给这个Connector写几个简单的方法,需要注意的是,这里的前后端的连接中需要使用到一个关键字Q_INVOKABLE 来修饰这个方法,这个关键字的作用是让QML可以调用这个方法。
这个主动上发的信号我这里会内部实现一个QTimer,每隔一秒发送一次sig_updateValue信号,为了更好的演示效果,我这里就不把QTimer的实现写进来了
#include <QObject>class Connector : public QObject
{Q_OBJECTpublic:Connector(QObject *parent);~Connector();Q_INVOKABLE void SetValue(const QString& string);Q_INVOKABLE QString getValue();signals:Q_INVOKABLE void sig_updateValue(const QString& string);
private:QString string;};
OK,现在万事俱备,只需要将Qt中的类注册到QML中去,暴露给QML系统就可以了,现在我们回到main.cpp,那个创建engine的地方,我们在这里将一个Connector的对象注册进到engine中去
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN) && QT_VERSION_CHECK(5, 6, 0) <= QT_VERSION && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endifQGuiApplication app(argc, argv);QQmlApplicationEngine engine;//engine.load(QUrl(QStringLiteral("qrc:/qt/qml/qds_toutor/main.qml")));//创建一个Connector对象,并注册connector对象到QML中Connector* connector = new Connector(nullptr);engine.rootContext()->setContextProperty("connector", connector);engine.load(QUrl(QStringLiteral("qrc:/content/App.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
现在我们的这个类就已经暴露在这个QML项目下了,现在我们回到QDS,从QDS中打开我们移植到C++项目中的QDS项目,再来进行编辑,现在我们实际上就可以直接在App.qml中直接调用connector这个对象了
有关主动调用的函数,我们直接调用connector的方法就好了,如下所示
Button {id: button1x: 43y: 108width: 67height: 28text: qsTr("写入参数")onClicked:{var string = textEdit.textconnector.setValue(string)}}Button {id: button2x: 126y: 108width: 64height: 28text: qsTr("读取参数")onClicked:{var string = connector.getValue()text1.text = string}}
这里已经可以直接将connector 的 setValue和getValue方法调用到了
有关从C++后端来的信号,我们这里需要写一个Connector来进行连接
Connections{target:connectoronSig_updateValue: {text2.text = strMessageconsole.log("Received signal from C++ with index:", strMessage)}
}
自此,这个项目就可以正常运行了
完成了基本功能,从UI界面上主动向下申请数据、以及后台向前台主动发送数据,这个项目算是完成了。
Github Link:LeventureQys/QDS_Toutor
相关文章:

[QDS]从零开始,写第一个Qt Design Studio到程序调用的项目
前言 最近在使用Qt Design Studio进行开发,但是简中网上要不就是只搜得到Qt Designer(Qt Creator内部库),要不就只搜得到一点营销号不知道从哪里搬来的账号,鉴于Qt Design Studio是一个这么强大的软件,自然是需要来进行一下小小的…...

Selenium Chrome Options 总结
ChromeOptions 是 Selenium 提供的一种工具,用于配置和自定义 Chrome 浏览器的启动行为。通过设置 ChromeOptions,可以添加扩展功能、设置无头模式、禁用弹窗等,满足多种测试需求。 1. 基本用法 初始化和应用 ChromeOptions from selenium…...

11、PyTorch中如何进行向量微分、矩阵微分与计算雅克比行列式
文章目录 1. Jacobian matrix2. python 代码 1. Jacobian matrix 计算 f ( x ) [ f 1 x 1 2 2 x 2 f 2 3 x 1 4 x 2 2 ] , J [ ∂ f 1 ∂ x 1 ∂ f 1 ∂ x 2 ∂ f 2 ∂ x 1 ∂ f 2 ∂ x 2 ] [ 2 x 1 2 3 8 x 2 ] \begin{equation} f(x)\begin{bmatrix} f_1x_1^22x_2\\…...

【软件方案】智慧城市,智慧园区,智慧校园,智慧社区,大数据平台建设方案,大数据中台综合解决方案(word原件)
第1章 总体说明 1.1 建设背景 1.2 建设目标 1.3 项目建设主要内容 1.4 设计原则 第2章 对项目的理解 2.1 现状分析 2.2 业务需求分析 2.3 功能需求分析 第3章 大数据平台建设方案 3.1 大数据平台总体设计 3.2 大数据平台功能设计 3.3 平台应用 第4章 政策标准保障…...

用js实现点击抽奖
用原生的JS来完成的一个小游戏,进行了简单的点击触发以及判断 css: <style>* {margin: 0;padding: 0;}body {background-color: #f7f7f7;display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;}.container {backg…...

Django 自定义路由转换器
步骤 创建自定义转换器类 必须定义 regex 属性(用于匹配参数)。必须实现 to_python 和 to_url 方法。 to_python: 将匹配的参数转换为视图函数可用的 Python 数据。to_url: 将数据转换为 URL 格式(用于反向解析)。 注册转换器 使用…...

【JavaEE初阶】枫叶经霜艳,梅花透雪香-计算机是如何运行的?
本篇博客给大家带来的是与计算机相关的知识点, 包括:计算机的组成, 指令, 进程(重点). 文章专栏: JavaEE初阶 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 1. 计算机的组成 1.1 计算机的发展史 计算…...

破解天然气巡检挑战,构建智能运维体系
一、行业现状 天然气行业在能源领域地位举足轻重,其工作环境高风险,存在有毒有害、易爆气体及高温等情况,且需持续监控设备运行状态,人工巡检面临巨大挑战与风险。好在随着科技发展,防爆巡检机器人的应用为天然气管道…...

go web单体项目 学习总结
为什么学习go 博主的主语言是Java,目前的工作也是做Java web开发,有了Java的经验后就想着再学一门语言,其实有两个原因,第一是基于兴趣,也想和Java对比下到底有什么不同,在学习go的时候让我更加了解了Java…...

Cocos游戏优化
在游戏开发中,性能优化是确保游戏流畅运行和玩家体验的关键环节。Cocos作为一款强大的开源游戏引擎,支持多平台开发,尤其在2D游戏开发领域有着显著优势。以下是一些针对 Cocos游戏优化的实用策略,旨在帮助开发者提升游戏性能和用户…...

wsl2的Ubuntu18.04安装ros和anaconda
参考:超详细 WSL2 安装 ros 和 anaconda_wsl2安装anaconda-CSDN博客 一.安装ros 1. 更换系统源 输入 wget http://fishros.com/install -O fishros && . fishros 和上面的链接一样,依次输入5-2-1 2. 安装ros 输入 wget http://fishros.c…...

基于迅为RK3568开发板全国产平台,快速实现APP开机自启动技术分享
应用场景: 在一些场景中需要系统启动以后就让应用程序运行起来,如闸机打卡系统,智能点餐系统,广告机系统等等。这个需求叫做自启动。 除全国产版本核心板以外,RK3568核心板还有工业级,商业级,连…...

C++网络编程之多播
概述 在移动互联网时代,随着多媒体应用的日益普及,如何高效地将数据传输给多个接收者成为了网络通信领域的一个重要课题。多播(英文为Multicast)作为一种高效的网络通信方式,可以将数据同时发送到多个接收者࿰…...

不只是请求和响应:使用Fiddler抓包URL和Method全指南(中)
欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! 不只是请求和响应:使用Fiddler抓包HTTP协议全指南(上)-CSDN博客https://blog.csdn.net/Chunfeng6yugan/article/details/144005872?spm1001.2014.3001.5502 🙉在(上)篇博客中…...

学习threejs,使用设置normalMap法向量贴图创建更加细致的凹凸和褶皱
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.MeshPhongMaterial高…...

Hive构建日搜索引擎日志数据分析系统
1.数据预处理 根据自己或者学校系统预制的数据 使用less sogou.txt可查看 wc -l sogou.txt 能够查看总行数 2.数据扩展部分 我的数据位置存放在 /data/bigfiles 点击q退出 将一个文件的内容传递到另一个目录文件下 原数据在 /data/bigfiles ->传递 到/data/workspac…...

Vue 3 defineModel: 简化组件的双向绑定
1. 引言 在 Vue 3.4 版本中,引入了一个新的组合式 API 函数 defineModel。这个函数大大简化了自定义组件中实现 v-model 的过程,使得创建具有双向绑定功能的组件变得更加直观和简洁。 © ivwdcwso (ID: u012172506) 2. defineModel 的基本概念 defineModel 是一个宏,它简…...

【Flutter】搭建Flutter开发环境,安卓开发
Flutter是谷歌开源的一个跨平台开发的框架,方便好用,这里以Windows 上构建 Flutter Android 应用为例,记录下我搭建环境时碰到的一些问题以及解决。 第一步:参考官网:开发 Android 应用 | Flutter 中文文档 - Flutter …...

Linux中的共享内存
在Linux中,共享内存是一种高效的进程间通信(IPC)机制,允许多个进程共享一块内存区域,从而实现数据的快速传递和共享。它的特点是可以直接访问共享的内存,无需额外的拷贝操作,因此速度非常快。 共…...

SpringBoot中忽略实体类中的某个属性不返回给前端的方法
使用Jackson的方式: //第一种方式,使用JsonIgnore注解标注在属性上,忽略指定属性 public class PropertyDTO {JsonProperty("disable")private Integer disable;JsonProperty("placeholder")private String placeholde…...

ubuntu 安装proxychains
在Ubuntu上安装Proxychains,你可以按照以下步骤操作: 1、更新列表 sudo apt-update 2、安装Proxychains sudo apt-get install proxychains 3、安装完成后,你可以通过编辑/etc/proxychains.conf文件来配置代理规则 以下是一个简单的配置示例&…...

pytorch四种单机多卡分布式训练方法
文章目录 1、原生pytorch(mp.spawn)2、pytorch ddp (torchrun)3、lightning fabric4、Hugging Face Accelerate4、总结与对比4.1 mp.spawn4.2 torchrun4.3 Lightning Fabric4.4 Hugging face accelerate pytorch 分布式训练的四种方法。 我将会产生一份伪数据0到19共…...

archlinux 触摸板手势配置
文章目录 [toc]libinput-gestures安装 libinput-gestures加入 input 组创建配置文件可用手势 启动 libinput-gestures停止 libinput-gestures自启动 libinput-gestures Touchpad Synapticssynaptics.4 在 /etc/X11/xorg.conf.d/ 目录下会有默认的触摸板配置文件,如果…...

djinn:1 靶场学习小记
一、测试环境: kail攻击机:Get Kali | Kali Linux 靶场镜像:https://download.vulnhub.com/djinn/djinn.ova 描述: 该机器与 VirtualBox 和 VMWare 兼容。DHCP 将自动分配一个 IP。您将在登录屏幕上看到 IP。您必须找到并读取分…...

kafka消费者组和分区数之间的关系是怎样的?
消费者组和分区数之间的关系决定了Kafka中消息的消费方式和负载均衡。合理配置分区数和消费者数量对于优化Kafka的性能和资源利用率至关重要。以下是这种关系的几个关键点: 一个分区只能被同一组的一个消费者消费:这是为了保证消息的顺序性。在同一个消费…...

【go】查询某个依赖是否存在于这个代理
1. 使用 go list 命令 go list -m -versions github.com/gin-gonic/gin 如果模块存在,该命令会返回模块及其可用版本: github.com/gin-gonic/gin v1.7.0 v1.7.1 v1.8.0如果模块不存在或无法找到,会返回错误。 2. 使用 curl 查询代理服务 …...

如何从postman中导出所有集合Collection
项目场景: 有时候需要备份或迁移到其他平台,我们需要在postman中将这些集合数据导出。导出 Postman 集合是为了备份、团队共享或平台迁移等目的的重要步骤。此过程可分为导出单个集合和批量导出所有集合两部分,确保已保存和更新集合后&#x…...

在 Spring Boot 中实现多种方式登录(用户名、手机号、邮箱等)的不正经指南
欢迎来到一场技术与幽默交织的冒险!今天,我们将跳进 Spring Boot 的世界,探索如何通过 用户名、手机号、邮箱 等多种方式实现登录。想象一下,用户在登录时可以随心所欲地选择——就像你今天早上纠结到底是要喝美式咖啡还是拿铁&am…...

.NET平台用C#添加动作到PDF文档
使用C#语言在.NET框架下向PDF文档中添加动作,不仅能够提升文档的交互性和用户体验,还能够在自动化工作流中发挥关键作用,例如自动跳转至特定页面、链接外部资源或播放音频资源等操作。这种能力使得开发者能够根据具体需求定制PDF文档的互动操…...

大数据治理:概念、框架与实践应用
摘要: 随着大数据时代的到来,数据量呈爆炸式增长,数据来源和类型日益多样化。大数据治理作为确保数据质量、安全性、合规性以及有效利用数据资产的关键领域,已成为企业和组织在数字化转型过程中面临的重要挑战和机遇。本文深入探讨了大数据治理的概念,详细阐述了其涵盖的主…...