前言:

已经从事QT开发几年了,但对于QML这个东西始终是没有彻底掌握,一方面实际工作中没有用到过,其次它的语法对我来说是全新的东西,不像QWidget那一套可以直接在C++中去写。这就是为什么网上都说qml更简单,我却屡屡学不会的原因。
让我下定决心一定要开始学QML的契机,就是因为最近在找工作,面试官让我在纸上直接写一个按钮,并设置一段文字,结果我犹豫半天,居然没能动笔。我大概知道是写button,然后用花括号括起来,但button是否需要大写,花括号后面有没有分号,里面的属性又是什么来着……我一下子陷进了沮丧。
这其实就是没有真正使用qml写过代码的必然结果,即便对此有基本的认知,但别人考到你的时候,实际上是写不出来的。所以接下来的学习当中,我必须要做好详细的记录和笔记,这也是对自己的要求。(偷偷抱怨一句,在这个时代只会qt,是真的难找到工作啊)
话不多说,

一、QML基本了解

QML是Qt框架的声明式UI开发语言,与传统的Qt Widgets(基于C++的界面库)在语法特性、适用场景和视觉效果上存在显著差异‌。

‌1.语法特性‌: QML采用JSON-like声明式语法,支持数据绑定和热重载。‌ Qt
Widgets使用C++编写,采用命令式编码模式。‌
2.视觉效果‌: QML支持矢量渲染与复杂动画,可自定义渐变色、圆角等效果。‌ Qt Widgets基于原生控件,动画效果有限。‌
3.开发场景‌: QML适合移动端/嵌入式设备的动态UI(占比65%应用场景)。‌ Qt Widgets适合传统桌面软件(如Office类应用)。‌

以上是网上找到的内容,结合我自身的认知,再浅浅谈一下。
1.QML常常伴随Qt Quick这个词语,看上去好像是同一个东西,实则不然。QML是Quick Markup Language,它是一门语言。而Qt Quick是一个模块,可以理解为Qt的一个扩展库,你必须要先引用Qt Quick这个模块,才能用QML语言来写代码。
2.为什么会出现QML这个东西,我猜是为了将界面描述和逻辑代码彻底分开。如果你深入用QWidget来写过代码,你会有个感悟,界面层的代码和业务功能代码是深度耦合在一起的,特别是还有信号槽这种东西。而如果我们将界面相关的东西,全部用单独的文件编写起来,业务代码继续用C++写,是不是就更清晰明了,分工明确呢。所以说,QML其实是专门做界面+加动画+小逻辑的语言,为的是不抢C++业务。
3.说到QML的优势,大家说的基本上可以使用GPU硬件加速和支持动画效果,但这方面我目前还没体会到,后面学习再加上。还有一点是,QML更方便应用在嵌入式小设备和移动端。至于“学习成本低”、“语法更简单”,就见仁见智了。

二、QML工程创建
先说一下,我的QT版本是5.14.2,默认就可以创建Qt Quick工程,如果不行可能是QT安装的时候没有安装对应的模块,这个就得重新装下QT了。
咱们先创建新的工程,选Qt Quick的应用工程,这里有好几个选项,直接选空的即可。后面的步骤和QWidget是一样的,就不啰嗦了。
在这里插入图片描述
创建完工程后,直接编译运行,成功显示出空白界面。(还很贴心给了个Hello World的提示)
在这里插入图片描述

三、工程结构

在看具体的qml代码之前,我们先看一下基本的工程目录结构。
如果是传统的QWidget工程,代码一般放在Headers(头文件)和Sources(源文件)两个目录下标里面,但存放qml代码的qml文件显然不是。你可以直观看到,qml文件默认是放在Resources底下的qrc里面的。而qrc一般存放的是资源文件,最常见的就是各种ui图片。
在这里插入图片描述
也就是说,qml作为一种界面描述文件,本质上是当做一种资源来管理的(不知道说得对不对),他区别于其他正式的C++代码文件,存放在不同的目录底下。
当然,这里所说的目录不是文件实际存放的目录,说得上qt IDE里面显示的分类目录哈。
在这里插入图片描述
咱们打开工程的pro文件,发现它加载的是quick模块。这里对比一下传统QWidget应用,这里夹在的事core和gui模块。
在这里插入图片描述
当然,这并不是二选一的问题,事实上qml是可以和widget混合使用的,比如从一个qwidget界面跳转到qt quick界面,是完全可以的。我想表达的是,如果我们在qwidget工程中,想要新增一个qml工程,需要自己手动在pro中添加quick模块,这样qml才能正常使用哈。

四、C++中打开并显示QML界面

我们直接把main中的代码放上来。咋一看很复杂,没事我们慢慢来。

#include <QGuiApplication>
#include <QQmlApplicationEngine>int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;const QUrl url(QStringLiteral("qrc:/main.qml"));QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);}, Qt::QueuedConnection);engine.load(url);return app.exec();
}

首先是头文件,这里引用的QGuiApplication,它实际上对应的是QApplication,QGuiApplication比QApplication会更加轻量级,更适合纯QML的工程。这里换成QApplication其实也是可以的,但pro要注意把core和gui模块加上。
第二个头文件叫QQmlApplicationEngine
QML 引擎,负责解析+加载+实例化你的 main.qml 文件。
我们看main的代码,第一行是QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);这是开启高分辨率自适应,这和qwidget是一样的,它默认给你添加了。
下一行是QGuiApplication app(argc, argv);这是创建了一个应用对象。
重点是下面的代码。

QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));

engine = QML 解析器 + 加载器 + 对象工厂。
url = 要加载的 QML 文件(qrc 资源系统路径)。

QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,&app, [url](QObject *obj, const QUrl &objUrl) {if (!obj && url == objUrl)QCoreApplication::exit(-1);
}, Qt::QueuedConnection);

这句信号槽实际上是engine引擎加载url后的结果回调,返回参数是obj和obj的url,这里做了个保险丝判断,如果 main.qml 加载失败(文件不存在/语法错误),立即退出程序,防止黑屏。

engine.load(url);
return app.exec();

load = 解析 + 实例化整个 QML 对象树。
exec() = 进入事件循环,直到 QCoreApplication::quit() 或窗口关闭。

最后再说一下我自己的理解。这种写法更多是初始化一个qml引擎,然后加载url上的文件,把qml描述的界面显示出来。实际上我更喜欢另一种方法,用到了qt中的QQuickWidget,它是一种组件,可以直接嵌QWidget中。直接调用QQuickWidget中的setSource似乎是一种更方便的做法,当然以我目前的水平,还说不好谁更好。这种方法我在下一篇中会详细再说。
至此,一个qml界面便显示出来咯。

五、QML最小可运行实例

我们双击main.qml,发现里面有这段代码。

import QtQuick 2.14
import QtQuick.Window 2.14Window {visible: truewidth: 640height: 480title: qsTr("Hello World")
}

类似于C++代码,其实还蛮好理解的。

  1. import QtQuick 2.14
    引入 QtQuick 核心库(对象、动画、绘制等基础类)。

  2. import QtQuick.Window 2.14
    引入 Window 组件(ApplicationWindow 的简化版),提供顶层窗口。

  3. Window { … }
    顶层窗口对象,等价于 QMainWindow 的 QML 版。

  4. visible: true
    立即显示窗口(false 则隐藏)。

  5. width: 640 / height: 480
    窗口初始大小(像素)。

  6. title: qsTr("Hello World")
    窗口标题,qsTr() 是 Qt 的国际化函数,可被翻译系统替换。

这 7 行是 QML 的最小可运行模板: 导入 QtQuick 和 Window,创建 640×480 的顶层窗口,标题‘Hello World’,立即显示。

六、顶层窗口描述

我再补充一点,这里用到的Window事实上并不是固定的,我有见过b站up主用的Rectangle,于是用kimi问了一下:

  • Window = 顶层窗口(有标题栏、系统边框、任务栏图标)。
  • Rectangle = 普通矩形对象(无边框,必须被别的窗口或组件装载)。

1. 顶层 vs 被装载

作用是否能独立显示
Window顶层窗口(系统边框、标题栏)✅ 直接显示
Rectangle矩形+颜色+子控件❌ 必须被 Window/ApplicationWindow 装载

2. 代码对比

顶层窗口(独立显示):

import QtQuick 2.14
import QtQuick.Window 2.14Window {                       ← 顶层窗口visible: truewidth: 640; height: 480Rectangle {                ← 被装载的矩形width: 200; height: 200color: "red"}
}

仅 Rectangle(无边框,需被装载):

import QtQuick 2.14
Rectangle {                    ← 无边框矩形width: 200; height: 200color: "red"
}

后者无法独立显示——必须被 Window/ApplicationWindow 或别的组件装载。


3. 常用顶层类对照

QML 类作用备注
Window最简顶层窗口无边框菜单
ApplicationWindow带菜单栏/工具栏的主窗口QtQuick.Controls 2 推荐
Rectangle普通矩形+子控件被装载对象

这就能解释得通了,因为Rectangle的方式是加载在QQuickWidget控件里面的,不像main.qml中的Window必须是顶层窗口。(我尝试直接将Window改成Rectangle,结果QQmlApplicationEngine加载返回的信号槽没有出错,但界面没有弹出来,不符合我们的预期。)
这一点跟QMainWindow和QWidget的设计是类似的。只是QWidget不仅可以作为子控件,其实还可以用作顶层窗口,如果做了相关设置,甚至可以变成dialog弹窗,不过这个就不细说了。

七、总结

写到这里,我已经尽可能说得很详细,也努力让自己印象深刻一点,毕竟这其实是自学笔记嘛。如果有人真的读到这里,有什么问题也可以在评论区提出。
如果可以的话,接下来我会按照自己的节奏,按照自己的理解,一点点更新这个学习笔记,要是能成为一个教程就更棒了。

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

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

相关文章

SAP HANA Scale-out 04:缓存

结果缓存静态结果缓存 Vs 动态结果缓存FeatureStatic Result CacheDynamic Result CacheTarget Scenario对复杂视图&#xff08;通常是顶层视图&#xff09;的查询频繁更新的大表&#xff08;例如ACDOCA&#xff09;上的聚合查询Query result非实时数据实时数据ScopeTarget obj…

嘉兴禾润 HTR7216 (S) LED 驱动芯片:特性与应用

在如今智能设备飞速普及的时代&#xff0c;无论是智能家居的氛围营造、IoT 设备的状态提示&#xff0c;还是个人消费电子的视觉呈现&#xff0c;都离不开高性能 LED 驱动芯片的支撑。嘉兴禾润推出的 HTR7216 (S) LED 驱动芯片&#xff0c;凭借丰富的功能、精准的控制以及出色的…

Python实现剑龙优化算法 (Stegosaurus Optimization Algorithm, SOA)优化函数(付完整代码)

Python实现剑龙优化算法 (Stegosaurus Optimization Algorithm, SOA)优化函数&#xff08;付完整代码&#xff09;1.剑龙优化算法介绍剑龙优化算法&#xff08;Stegosaurus Optimization Algorithm&#xff0c;SOA&#xff09;是一种受剑龙独特生理结构和行为模式启发而设计的元…

分布式拜占庭容错算法——权益证明(PoS)算法详解

Java 实现权益证明&#xff08;PoS&#xff09;算法详解 一、PoS 核心机制 #mermaid-svg-Sbj0HU6MjOl1yo5L {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Sbj0HU6MjOl1yo5L .error-icon{fill:#552222;}#mermaid-s…

【论文阅读】谷歌:生成式数据优化,只需请求更好的数据

谷歌DeepMind团队通过Generative Data Refinement&#xff08;GDR&#xff09;技术&#xff0c;成功将极端有毒的4chan讨论数据转化为安全且语义丰富的训练素材&#xff0c;推动了LLM训练数据净化的新范式&#xff1a; • GDR利用预训练大模型对原始数据进行“重写”&#xff0…

C++ 多线程实战 10|C++20 的信号量、闩锁与屏障

目录 前言 学习目标 1. 信号量&#xff08;Semaphore&#xff09; 示例&#xff1a;限制并发下载任务 2. 闩锁&#xff08;Latch&#xff09; 示例&#xff1a;赛跑 3. 屏障&#xff08;Barrier&#xff09; 示例&#xff1a;图像处理流水线 4. 常见坑与对策 5. 实践作…

【Java SE】01. 初识Java

1. 认识Java Java是一种优秀的程序设计语言&#xff0c;它具有令人赏心悦目的语法和易于理解的语义。Java还是一个有一系列计算机软件和规范形成的技术体系&#xff0c;这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境&#xff0c;并广泛应用于嵌入式系统、移动终…

解锁仓储智能调度、运输路径优化、数据实时追踪,全功能降本提效的智慧物流开源了

AI 视频监控平台&#xff1a;全链路协同驱动的智能监控解决方案AI 视频监控平台是一款融合高性能功能与轻量化操作的实时算法驱动型视频监控系统&#xff0c;其核心愿景在于深度破除不同芯片厂商间的技术壁垒&#xff0c;省去冗余重复的适配环节&#xff0c;最终达成芯片、算法…

冒泡排序与选择排序以及单链表与双链表

1. 冒泡排序&#xff08;Bubble Sort&#xff09; 1. 原理 冒泡排序是一种 简单的排序算法&#xff0c;通过 两两比较相邻元素&#xff0c;把较大的元素逐渐 “冒泡” 到数组末尾。 思路&#xff1a; 从数组头开始&#xff0c;比较相邻两个元素。 如果前一个比后一个大&…

Python实现计算点云投影面积

本次我们分享一种基于 Open3D 的快速、稳健方法&#xff0c;用于从激光点云中自动提取“地面”并计算其投影面积。算法先自适应估计地面高程&#xff0c;再将地面点投影至水平面&#xff0c;随后用凸包或最小外接矩形求取面积。整个流程无需人工干预&#xff0c;单文件即可运行…

AXI4 协议

一、AXI4简介AXI4&#xff08;Advanced eXtensible Interface 4&#xff09;是ARM公司推出的高性能片上总线协议&#xff0c;属于AMBA&#xff08;Advanced Microcontroller Bus Architecture&#xff09;标准的一部分。它专为高带宽、低延迟的片上通信设计&#xff0c;广泛应用…

《饿殍:明末千里行》Switch版试玩发布 3月13日发售

使用jQuery的常用方法与返回值分析 jQuery是一个轻量级的JavaScript库&#xff0c;旨在简化HTML文档遍历和操作、事件处理以及动画效果的创建。本文将介绍一些常用的jQuery方法及其返回值&#xff0c;帮助开发者更好地理解和运用这一强大的库。 1. 选择器方法 jQuery提供了多种…

[特殊字符] 认识用户手册用户手册(也称用户指南、产品手册)是通过对产品功能的清

一份优秀的用户手册能有效降低用户的使用门槛&#xff0c;提升用户体验和工作效率。下面我将为你梳理编写用户手册的核心要点、步骤和技巧。&#x1f4d6; 认识用户手册用户手册&#xff08;也称用户指南、产品手册&#xff09;是​​通过对产品功能的清晰解释&#xff0c;为特…

苹果软件代码混淆,iOS混淆、iOS加固、ipa安全与合规取证注意事项(实战指南)

在移动软件交付与合规审计中&#xff0c;苹果软件代码混淆已成为保护知识产权与用户数据的常规手段。但混淆带来的不仅是逆向难度的提升&#xff0c;也会触发崩溃取证、符号化&#xff08;symbolication&#xff09;、审计合规与法律证据保存等问题。本文从工程与合规双视角出发…

Redis框架详解

目录 1. redis是什么 主要特点 2. redis中存储的数据类型 2.1 String类型 2.2 List类型 2.3 Hash类型 2.4 Set类型 2.5 Zset类型 2.6 其它类型 3.redis高可用框架 1. redis是什么 Redis 是一个开源的、基于内存的数据结构存储系统&#xff0c;是 Remote Dictionary…

每日随机展示10个wordpress置顶文章

WordPress 置顶文章是博主根据自己的需要设置的&#xff0c;通常用于展示重要或热门的文章。 以下是一个示例代码&#xff0c;用于在 WordPress 主题中展示 10 个置顶文章&#xff1a; <?php // 查询置顶文章 $sticky get_option(sticky_posts); $args array(post__in …

金融工程vs金融数学:谁更贴近量化交易?

在金融行业迈向高度数字化的今天&#xff0c;量化交易已成为顶尖金融机构的核心竞争力之一。它以数学模型为基础&#xff0c;借助编程技术实现策略自动化&#xff0c;在高频、中低频、套利、因子投资等多个领域展现出强大生命力。对于有志于此的大学生而言&#xff0c;选择一个…

实测AI Ping,一个大模型服务选型的实用工具

作为一名长期奋战在一线的AI应用工程师&#xff0c;我在技术选型中最头疼的问题就是&#xff1a;“这个模型服务的真实性能到底如何&#xff1f;” 官方的基准测试总是在理想环境下进行&#xff0c;而一旦投入使用&#xff0c;延迟波动、吞吐下降、高峰期服务不可用等问题就接踵…

深信服软件:aTrustAgent异常占用问题处理

问题&#xff1a;aTrustAgent占用CPU 大早上开电脑&#xff0c;风扇转的飞起&#xff0c;任务管理器看&#xff0c;发现是有几个 aTrustAgent 进程搞得鬼。 印象中&#xff0c;好像没有装过这个软件&#xff0c;搜了下&#xff0c;是深信服的软件&#xff0c;不知道是不是装哪…

基于国产银河麒麟服务器SP3项目实战(Nginx+Keepalive)实现高可用负载均衡

一、环境准备 192.168.113.11NginxKeepalive(Master)192.168.113.22Nginxkeepalive(Backup)192.168.113.33Nginx(web服务器)192.168.113.44 Nginx(服务器&#xff09; 二、环境搭建准备 2.1 Nginx源码编译安装 参考作责之前发布《Nginx源码编译安装》https://blog.csdn.net…