【QT】 控件 -- 显示类

### 🔥 目录

  • [@[TOC]( 🔥 目录)](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [1. 前言](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [2. 显示类控件](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [2.1 Label](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [1、显示不同文本](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [2、显示图片](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [3、文本对齐、自动换行、缩进、边距](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [4、设置伙伴](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [3.2 LCD Number](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [3.3 ProgressBar](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [3.4 Calendar Widget](#🔥 目录 @[TOC]( 🔥 目录) 1. 前言 2. 显示类控件 2.1 Label 1、显示不同文本 2、显示图片 3、文本对齐、自动换行、缩进、边距 4、设置伙伴 3.2 LCD Number 3.3 ProgressBar 3.4 Calendar Widget 3. 共勉 🔥)
  • [3. 共勉 🔥](#🔥 目录 @[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 可以用来显示文本和图片,核心属性如下:

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

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

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

2、显示图片

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3.2 LCD Number

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

属性 说明
intValue QLCDNumber 显示的数字值(整数)。与 value 联动,显示整数值。
value QLCDNumber 显示的数字值(浮点数)。与 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

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

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

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

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

handle 实现

  • 通过 intValue 获取到 QLCDNumber 内部的数值。
  • 如果 value 的值归 0 了,就停止 QTimer,接下来 QTimer 也就不会触发 timeout 信号了。
  • 可以看到每隔一秒钟,显示的数字就减少 1:通过 timer ms & lcd -1 实现

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

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

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

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

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

这个代码同样也是不行的

"理想很美好,现实很骨感"

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

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

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

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

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

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

3.3 ProgressBar

使用 QProgress Bar 表示一个进度条

  • 注意:不要把 ProgessBar 拼写成 ProcessBar
属性 说明
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:

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


这里有个小小的问题:虽然在 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

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

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

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

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


【实现其他颜色进度条】

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

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

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

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

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

3.4 Calendar Widget

QCalendarWidget 表示⼀个 "日历",形如:

核心属性 说明
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

(2)给 QCalendarWidget 添加 slot 函数 selectionChanged

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

3. 共勉 🔥

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

相关推荐
Eiceblue1 小时前
Python 合并 Excel 单元格
开发语言·vscode·python·pycharm·excel
码农客栈2 小时前
qt QNetworkRequest详解
qt
SomeB1oody2 小时前
【Rust自学】15.2. Deref trait Pt.1:什么是Deref、解引用运算符*与实现Deref trait
开发语言·后端·rust
Say-hai2 小时前
QT6 + CMAKE编译OPENCV3.9
qt·opencv
情深不寿3173 小时前
C++----STL(list)
开发语言·c++
boonya3 小时前
Yearning开源MySQL SQL审核平台
数据库·mysql·开源
SomeB1oody3 小时前
【Rust自学】15.4. Drop trait:告别手动清理,释放即安全
开发语言·后端·rust
liruiqiang053 小时前
DDD-全面理解领域驱动设计中的各种“域”
开发语言·架构
前端熊猫3 小时前
JavaScript 的 Promise 对象和 Promise.all 方法的使用
开发语言·前端·javascript
weixin_421133414 小时前
编写python 后端 vscode 安装插件大全
开发语言·vscode·python