【QT】 控件 -- 显示类

🔥 目录

    • @[TOC]( 🔥 目录)
    • 1. 前言
    • 2. 显示类控件
      • 2.1 Label
        • 1、显示不同文本
        • 2、显示图片
        • 3、文本对齐、自动换行、缩进、边距
        • 4、设置伙伴
      • 3.2 LCD Number
      • 3.3 ProgressBar
      • 3.4 Calendar Widget
    • 3. 共勉 🔥


1. 前言

之前我在上一篇文章【QT】-- 按钮类已经说了QT 控件按钮类方面的知识以及涉及到的各种属性/函数/使用方法,现在就来开始了解显示类的相关知识啦

2. 显示类控件

2.1 Label

QLabel 可以用来显示文本和图片,核心属性如下:

属性说明
textQLabel 中的文本。用于显示在标签上的文字内容。
textFormat文本的格式:
- Qt::PlainText:纯文本
- Qt::RichText:富文本(支持 HTML 标签)
- Qt::MarkdownText:Markdown 格式
- Qt::AutoText:根据文本内容自动决定文本格式。
pixmapQLabel 内部包含的图片。用于显示静态图像
scaledContents设置为 true 表示内容自动拉伸填充 QLabel;设为 false 则不会自动拉伸。
alignment对齐方式。可以设置水平和垂直方向如何对齐,例如居中、左对齐等。
wordWrap设置为 true 内部的文本会自动换行;设为 false 则内部文本不会自动换行。
indent设置文本缩进。影响水平和垂直方向的缩进。具体生效的方向取决于 alignment 属性。
margin内部文本和边框之间的边距。不同于 indentmargin 在上下左右四个方向都同时有效。
openExternalLinks是否允许打开一个外部链接。当 QLabel 文本内容包含 URL 时,点击链接将尝试打开浏览器访问该 URL。
buddyQLabel 关联一个“伙伴”,点击 QLabel 时能激活对应的伙伴控件。例如,如果伙伴是一个 QCheckBox,那么该 QCheckBox 将被选中。
1、显示不同文本

(1)在界面上创建四个 QLabel,尺存放大一些,objectName 分别为 label、label_2、label_3、label_4

image-20250116183518665

(2)修改 widget.cpp,设置四个 label 的属性 ⭕

image-20250116183707404

2、显示图片

虽然 QPushButton 也可以通过设置图标的方式设置图片,但是并非是一个好的选择,更多的时候还是希望通过 QLabel 来作为一个更单纯的显示图片的方式。

(1)在界面上创建一个 QLabel,objectName 为 label

image-20250116193035454

(2)创建 resource.qrc 文件,并把图片导入到 qrc 中,修改 widget.cpp,给 QLabel 设置图片,给窗口(800 * 600)设置合适尺寸,修改代码,设置 scaledContents 属性,如下:

image-20250116194047516

  • 一旦程序运行起来,QLabel 的尺寸就固定了,如果拖动窗口大小,可以看到图片并不会随着窗口大小的改变而同步变化。

为了解决这个问题,可以在 Widget 中重写 resizeEvent 函数:

image-20250116200038932

  • 执行程序,此时改变窗口大小,图片也会随之变化:

注意:要记得把函数 在.h 文件中,声明一下

image-20250116195932188

注意:这里的 resizeEvent 函数我们没有手动调用,但是能在窗口大小变化时被自动调用,这个过程就是依赖 C++ 中的多态来实现的。

  • Qt 框架内部管理着 QWidget 对象表示我们的窗口,在窗口大小发生改变时,Qt 就会自动调用 resizeEvent 函数
  • 但是由于实际上这个表示窗口的并非是 QWidget,而是 QWidget 的子类,也就是我们自己写的 Widget
  • 此时虽然是通过父类调用函数,但是实际上执行的是子类的函数(也就是我们重写后的 resizeEvent)
  • 获取到窗口的 event,进行 resize 处理

此处属于是多态机制的⼀种经典用法。通过上述过程就可以把自定义的代码插入到框架内部执行,相当于 “注册回调函数”

3、文本对齐、自动换行、缩进、边距

(1)创建四个 label,objectName 分别是 label 到 label_4,并且在 QFrame 中设置 frameShape 为 Box(设置边框之后看起来会更清晰一些)

img

image-20250116202103244

QFrame 是 QLabel 的父类,其中 frameShape 属性用来设置边框性质:

  • QFrame::Box:矩形边框
  • QFrame::Panel:带有可点击区域的面板边框
  • QFrame::WinPanel:Windows 风格的边框
  • QFrame::HLine:水平线边框
  • QFrame::VLine:垂直线边框
  • QFrame::StyledPanel:带有可点击区域的面板边框,但样式取决于窗口主题。

(2)编写 widget.cpp,给这四个 label 设置属性,运行程序

image-20250116202923548

  • 此处设置的文本缩进,后续的行也会产生缩进,不仅仅是首行缩进
4、设置伙伴

(1)创建两个 label 和 两个 radioButton,objectName 分别为 label、label_2、radioButton_A、radioButton_B

image-20250116203746412

此处把 label 中的文本设置为 “快捷键 &A” 这样的形式。

  • 其中 & 后面跟着的字符就是快捷键,可以通过 alt + A 的方式来触发该快捷键。

  • 但是注意,这里的快捷键和 QPushButton 的不同 需要搭配 alt 和 单个字母的方式才能触发。

  • 绑定了伙伴关系之后,通过快捷键就可以选中对应的单选按钮 / 复选按钮。

(2)编写 widget.cpp,设置 buddy 属性【当然这里也可以使用 Qt Designer 直接设置】

image-20250116203724395

  • 可以看到,按下快捷键 alt + a 或者 alt + b,即可选中对应的选项

3.2 LCD Number

QLCDNumer 是一个专门用来显示数字的控件,类似于 “老式计算器” 的效果。

image-20250116203917643

属性说明
intValueQLCDNumber 显示的数字值(整数)。与 value 联动,显示整数值。
valueQLCDNumber 显示的数字值(浮点数)。与 intValue 联动,设置此属性时会自动四舍五入到最近的整数。
例如,给 value 设为 1.5,intValue 的值就是 2。
设置 valueintValue 的方法名为 display,而不是 setValuesetIntValue
digitCount显示几位数字。设置可以显示的最大位数。
mode数字显示形式:
- QLCDNumber::Dec:十进制模式,显示常规的十进制数字。
- QLCDNumber::Hex:十六进制模式,以十六进制格式显示数字。
- QLCDNumber::Bin:二进制模式,以二进制格式显示数字。
- QLCDNumber::Oct:八进制模式,以八进制格式显示数字。
只有在十进制模式下才能显示小数点后的内容。
segmentStyle设置显示风格:
- QLCDNumber::Flat:平面的显示风格,数字呈现在一个平坦的表面上。
- QLCDNumber::Outline:轮廓显示风格,数字具有清晰的轮廓和阴影效果。
- QLCDNumber::Filled:填充显示风格,数字被填充颜色并与背景区分开。
smallDecimalPoint设置较小的小数点。当启用时,小数点将使用更小的段来表示,节省空间并提高显示密度。

【实现倒计时功能】

(1)在界面上创建⼀个 QLCDNumber,初始值设为 10,objectNamelcdNumber

image-20250116210530615

(2)修改 widget.h 代码,创建一个 QTimer 成员 和一个 handle 函数

image-20250116210827930

(3)修改 widget.cpp,在构造函数中初始化 QTimer

  • QTimer 表示定时器,通过 start 方法启动定时器之后,就会每隔一定周期触发一次 QTimer::timeout 信号

  • 使用 connectQTimer::timeout 信号和 Widget::updateTime 连接起来,意味着每次触发 QTimer::timeout 都会执行 Widget::updateTime

handle 实现

  • 通过 intValue 获取到 QLCDNumber 内部的数值。
  • 如果 value 的值归 0 了,就停止 QTimer,接下来 QTimer 也就不会触发 timeout 信号了。

image-20250116211546619

  • 可以看到每隔一秒钟,显示的数字就减少 1:通过 timer ms & lcd -1 实现

💡 欸,针对上面代码我们来两个操作 >

操作一:如果直接在上述 Widget 构造函数中,通过一个循环 + sleep 的方式是否可以呢?

image-20250116212048666

  • 显然,上面这段代码是不行的,循环会使 *Widget 的构造函数无法执行完毕*,此时界面是不能正确构造和显示的。

操作二:如果直接在上述 Widget 构造函数中,另起一个线程,在新线程中完成循环 + sleep 是否可以呢?

image-20250116212404395

  • 上面在 thread 的构造函数中传递了 一个 lambda 表达式,然后在在 lambda 表达式内部,定义了一个无限循环(while (true)),用于持续更新 QLCDNumber 的显示值。

image-20250116212542167

这个代码同样也是不行的

“理想很美好,现实很骨感”

  • Qt 中规定:任何对于 GUI 上内容的操作必须在主线程中完成
  • 像 Widget 构造函数,以及 connect 连接的 slot 函数,都是在主线程中调用的。
  • 而我们自己创建的线程则不是,当我们自己的线程中尝试对界面元素进行修改时,Qt 程序往往会直接崩溃。

这样的约定主要是因为 GUI 中的状态往往是牵一发动全身的,修改一个地方,就需要同步的对其他内容进行调整。

  • 比如调整了某个元素的尺存,就可能影响到内部的文字位置,或者其他元素的位置。这里一连串的修改都是需要按照一定的顺序来完成的。

  • 由于多线程执行的顺序无法保障,因此 Qt 从根本上禁止了其他线程修改 GUI 状态,避免后续的一系列问题。

  • 对于 Qt 的槽函数来说,默认情况下,槽函数都是由主线程调用到,在槽函数中修改界面是没有任何问题的。

综上所述,使用定时器是实现上述功能的最合理方案。后续如果也有类似的需要 “周期性修改界面状态” 的需求也需要优先考虑使用定时器。

3.3 ProgressBar

使用 QProgress Bar 表示一个进度条

  • 注意:不要把 ProgessBar 拼写成 ProcessBar

image-20250116213513843

属性说明
minimum进度条最小值。定义进度条的起始值,默认为 0
maximum进度条最大值。定义进度条的结束值,默认为 100
value进度条当前值。表示进度条中已完成的部分,介于 minimummaximum 之间。
alignment文本在进度条中的对齐方式:
- Qt::AlignLeft:左对齐
- Qt::AlignRight:右对齐
- Qt::AlignCenter:居中对齐
- Qt::AlignJustify:两端对齐
extVisible进度条的数字是否可见。设置为 true 时显示进度数值,false 则隐藏。
orientation进度条的方向是水平还是垂直。
- Qt::Horizontal:水平方向
- Qt::Vertical:垂直方向
invertAppearance是否朝反方向增长进度。如果设为 true,则进度从最大值向最小值递减。
textDirection文本的朝向。影响文本在进度条中的排列方向。
format展示的数字格式:
- %p:表示进度的百分比(0-100)
- %v:表示进度的数值(0-100)
- %m:表示剩余时间(以毫秒为单位)
- %t:表示总时间(以毫秒为单位)

【实现进度条按时间增长功能】

(1)在界面上创建进度条,objectNameprogressBar,其中最小值设为 0,最大值设为 100,当前值设为 0:

image-20250116213536771

(2)修改 widget.h,创建 QTimer 和 handle 函数

image-20250116213536771


这里有个小小的问题:虽然在 widget.h 中用到了 QTimer,但是却没在 widget.h 文件中包含 头文件,为什么这个代码编译没有出错呢?

上述问题其实是通过 Qt 内部提供的一个特殊技巧来实现的。

  • 在 Qt 中有一个专门的头文件(#include ),这个头文件中包含了 Qt 中所有类的 “前置声明”class QWidgetclass QPushButtonclass QTimer)。

  • 这个头文件我们一般不会直接接触到,但是包含其它的 Qt 的头文件,都会间接的包含到这个头文件。

  • 如果 Widget 类的前面以及提供了 QTimer 类的声明的话,此时就可以在 Widget 中声明 QTimer 的指针 / 引用类型的成员。

  • 后续如果要真正使用 QTimer 的头文件(包括创建实例,使用里面的成员),仍然要包含 QTimer 的头文件(包含了 QTimer 的详细的类的定义)。

那么Qt 为什么要使用上述技巧呢?上述技巧能解决什么问题?有什么提升呢?

主要解决的是编译速度的问题。

  • C/C++ 代码,编译速度在其他语言横向对比中是非常慢的。
  • C++ 编译速度慢和 #include 头文件有直接关系
  • 由于 include 关系错综复杂,所以尽可能减少 include 头文件的个数就可以有效地减少编译时间
  • Qt 中就使用 class 前置声明的方式来尽量减少头文件的包含。通过前置声明的方式,Qt 中每个头文件包含的其它头文件数量都能得到一定的降低。

(3)修改 widget.cpp,初始化 QTimer,此处设置 100 ms 触发一次 timeout 信号,也就是 ⼀秒钟触发 10 次,并且实现 handle

image-20250116214551637

在实际开发中,进度条的取值往往是根据当前任务的实际进度来进行设置的

  • 比如需要读取一个很大的文件,就可以获取文件的总的大小和当前读取完毕的大小,来设置进度条的比例。

  • 由于前面我们介绍了 Qt 禁止在其他线程修改界面,因此进度条的更新往往也是需要搭配定时器来完成的。

  • 通过 定时器周期触发信号,主线程调用对应的 slot 函数,再在 slot 函数中对当前的任务进度进行计算,并更新进度条的界面效果。


【实现其他颜色进度条】

上述的进度条是用绿色表示的,但是考虑到有些人可能不喜欢绿⾊,因此我们改成一个红色的进度条。

QProgressBar 同样也是 QWidget 的子类,因此我们可以使用 styleSheet 通过样式来修改进度条的颜色。

(1)代码不变,然后去在 Qt Designer 右侧的属性编辑器中找到 QWidget 的 styleSheet 属性(之前有讲过),编辑内容:其中的 chunk 是选中进度条中的每个 “块”,使用 QProgressBar::text 则可以选中文本。

image-20250116215429395

  • 但是我们发现当我们设置完之后,进度条中的数字会跑到左上角,因此我们还需要把 QProcessBaralignment属性设置为垂直水平居中

image-20250116215243314

此时就可以得到同上面效果一样,但是颜色不同的进度条了,同样的,通过上述方式,也可以修改文字的颜色,字体大小等样式。

3.4 Calendar Widget

QCalendarWidget 表示⼀个 “日历”,形如:

image-20250116215740767

核心属性说明
selectDate当前选中的日期。
minimumDate最小日期,定义用户可以选择的最早日期。
maximumDate最大日期,定义用户可以选择的最晚日期。
firstDayOfWeek每周的第一天(也就是日历的第一列)是周几。
gridVisible是否显示表格的边框,默认为 true 显示边框。
selectionMode是否允许选择日期。可以设置为单选或不选。
navigationBarVisible日历上方标题是否显示,默认为 true 显示导航栏。
horizontalHeaderFormat日历上方标题显示的日期格式,控制顶部标题栏的内容。
verticalHeaderFormat日历第一列显示的内容格式,控制左侧垂直标题栏的内容。
dateEditEnabled是否允许日期被编辑,默认为 false 不可编辑。
重要信号说明
selectionChanged(const QDate&)当选中的日期发生改变时发出。参数是一个 QDate 类型,保存了新的选中日期。
activated(const QDate&)当双击一个有效的日期或者按下回车键时发出。参数是一个 QDate 类型,保存了选中的日期。
currentPageChanged(int, int)当年份月份改变时发出。参数表示改变后的新年份和月份,分别为 int 类型。

【获取选中的日期】

(1)在界面上创建一个 QCalendarWidget 和一个 label,objectName 分别为 calendarWidget,label

image-20250116220455567

(2)给 QCalendarWidget 添加 slot 函数 selectionChanged

image-20250116220711232

  • 上面当选择不同的日期时,label 中的内容也会随之改变

3. 共勉 🔥

★,°:.☆( ̄▽ ̄)/$:.°★ 】那么本篇到此就结束啦,如果有不懂 和 发现问题的小伙伴可以在评论区说出来哦,同时我还会继续更新关于【QT】的内容,请持续关注我 !!
在这里插入图片描述

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

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

相关文章

前端-Rollup

Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由…

网络直播时代的营销新策略:基于受众分析与开源AI智能名片2+1链动模式S2B2C商城小程序源码的探索

摘要:随着互联网技术的飞速发展,网络直播作为一种新兴的、极具影响力的媒体形式,正逐渐改变着人们的娱乐方式、消费习惯乃至社交模式。据中国互联网络信息中心数据显示,网络直播用户规模已达到3.25亿,占网民总数的45.8…

STM32调试手段:重定向printf串口

引言 C语言中经常使用printf来输出调试信息,打印到屏幕。由于在单片机中没有屏幕,但是我们可以重定向printf,把数据打印到串口,从而在电脑端接收调试信息。这是除了debug外,另外一个非常有效的调试手段。 一、什么是pr…

利用飞书机器人进行 - ArXiv自动化检索推荐

相关作者的Github仓库 ArXivToday-Lark 使用教程 Step1 新建机器人 根据飞书官方机器人使用手册,新建自定义机器人,并记录好webhook地址,后续将在配置文件中更新该地址。 可以先完成到后续步骤之前,后续的步骤与安全相关&…

混合专家模型MoE的全面详解

什么是混合专家(MoE)? 混合专家(MoE)是一种利用多个不同的子模型(或称为“专家”)来提升LLM质量的技术。 MoE的两个主要组成部分是: 专家:每个前馈神经网络&#xff08…

基于Arcsoft的人脸识别

目录 一、前言 二、使用方法 三、获取SDK 四、人脸检测/人脸识别 五、代码实现 一、前言 face++,百度ai,虹软,face_recognition,其中除了face_recognition是python免费的一个库安装好响应的库直接运行就好,另外三个需要填入相关申请的信息id和key。 分别对应着相应的人…

电梯系统的UML文档13

5.2.6 CarPositionControl 的状态图 图 24: CarPositionControl 的状态图 5.2.7 Dispatcher 的状态图 图 25: Dispatcher 的状态图 5.3 填补从需求到状态图鸿沟的实用方法 状态图能对类的行为,一个用例,或系统整体建模。在本文中,状态图…

Ollama windows安装

Ollama 是一个开源项目,专注于帮助用户本地化运行大型语言模型(LLMs)。它提供了一个简单易用的框架,让开发者和个人用户能够在自己的设备上部署和运行 LLMs,而无需依赖云服务或外部 API。这对于需要数据隐私、离线使用…

C++二叉树进阶

1.二叉搜索树 1.1二叉搜索树概念 二叉搜索树又称二叉排序树,它或者是一颗空树,或者具有以下性质的二叉树 若它的左子树不为空,则左子树上所有结点的值小于根节点的值若它的右子树不为空,则右子树上所有节点的值都大于根节点的值…

亲测有效!解决PyCharm下PyEMD安装报错 ModuleNotFoundError: No module named ‘PyEMD‘

解决PyCharm下PyEMD安装报错 PyEMD安装报错解决方案 PyEMD安装报错 PyCharm下通过右键自动安装PyEMD后运行报错ModuleNotFoundError: No module named ‘PyEMD’ 解决方案 通过PyCharm IDE python package搜索EMD-signal,选择版本后点击“install”执行安装

2. Java-MarkDown文件解析-工具类

2. Java-MarkDown文件解析-工具类 1. 思路 读取markdown文件的内容&#xff0c;根据markdown的语法进行各个类型语法的解析。引入工具类 commonmark 和 commonmark-ext-gfm-tables进行markdown语法解析。 2. 工具类 pom.xml <!-- commonmark 解析markdown --> <d…

U盘打开提示格式化:深度解析与数据恢复全攻略

在数字化时代&#xff0c;U盘作为便捷的数据存储和传输工具&#xff0c;广泛应用于各个领域。然而&#xff0c;当我们满怀期待地插入U盘&#xff0c;却遭遇“U盘打开提示格式化”的尴尬局面时&#xff0c;那份焦虑与无助感油然而生。本文将全面剖析U盘打开提示格式化的原因、应…

HTB:Forest[WriteUP]

连接至HTB服务器并启动靶机 分配IP&#xff1a;10.10.16.21 靶机IP&#xff1a;10.10.10.161 靶机Domain&#xff1a;forest.htb 目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端…

芯片AI深度实战:实战篇之vim chat

利用vim-ollama这个vim插件&#xff0c;可以在vim内和本地大模型聊天。 系列文章&#xff1a; 芯片AI深度实战&#xff1a;基础篇之Ollama-CSDN博客 芯片AI深度实战&#xff1a;基础篇之langchain-CSDN博客 芯片AI深度实战&#xff1a;实战篇之vim chat-CSDN博客 芯片AI深度…

JavaScript - Web APIs(下)

日期对象 目标&#xff1a;掌握日期对象&#xff0c;可以让网页显示日期 日期对象&#xff1a;用来表示时间的对象 作用&#xff1a;可以得到当前系统时间 学习路径&#xff1a; 实例化 日期对象方法 时间戳 实例化 目标&#xff1a;能够实例化日期对象 在代码中发…

【安全测试】测开方向学习遇到的问题记录

【问题一】springboot如何访问静态资源文件 springboot启动根路径位置 F:\untitled05\demo4\src\main\resources\static 例如图片位置存放在F:\untitled05\demo4\src\main\resources\static即可 配置文件配置 spring.web.resources.static-locationsfile:/F:/untitled05/de…

Unity|小游戏复刻|见缝插针2(C#)

控制针的运动 新建一个Pin脚本 将Pin脚本拖到针Pin的下面 保存代码 using UnityEngine;public class Pin : MonoBehaviour {public float speed 5;private bool isFly false;private bool isReach false;private Transform startPosition;// Start is called once bef…

2025年数学建模美赛 A题分析(3)楼梯使用方向偏好模型

2025年数学建模美赛 A题分析&#xff08;1&#xff09;Testing Time: The Constant Wear On Stairs 2025年数学建模美赛 A题分析&#xff08;2&#xff09;楼梯磨损分析模型 2025年数学建模美赛 A题分析&#xff08;3&#xff09;楼梯使用方向偏好模型 2025年数学建模美赛 A题分…

DeepSeek大模型技术解析:从架构到应用的全面探索

一、引言 在人工智能领域&#xff0c;大模型的发展日新月异&#xff0c;其中DeepSeek大模型凭借其卓越的性能和广泛的应用场景&#xff0c;迅速成为业界的焦点。本文旨在深入剖析DeepSeek大模型的技术细节&#xff0c;从架构到应用进行全面探索&#xff0c;以期为读者提供一个…

「AI学习笔记」深度学习的起源与发展:从神经网络到大数据(二)

深度学习&#xff08;DL&#xff09;是现代人工智能&#xff08;AI&#xff09;的核心之一&#xff0c;但它并不是一夜之间出现的技术。从最初的理论提出到如今的广泛应用&#xff0c;深度学习经历了几乎一个世纪的不断探索与发展。今天&#xff0c;我们一起回顾深度学习的历史…