news 2026/5/8 15:49:16

Qt常用控件-> 2、按钮类控件、显示类控件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Qt常用控件-> 2、按钮类控件、显示类控件

回顾常用控件文章

Qt常用控件-> 1、概述、QWidget核心属性-CSDN博客


一、按钮类控件

1、Push Button

使用QPushButton表示一个按钮,这也是当前我们最熟悉的一个控件了。QPushButton继承自QABstractButton,这个类是一个抽象类,是其他按钮的父类

在Qt Designer中也能够看到这里的继承关系:

QAbstractButton中,和QPushButton相关性较大的属性:

1、QAbstractButton作为QWidget的子类,当然也继承了QWidget的属性。上面介绍的QWIdget里的各种属性用法,对于QAbstractButton同样适用,因表格仅列出QAbstractButton独有属性

2、Qt的api设计风格是非常清晰的,此处列出的属性都是可以获取和设置的。例如,使用text()获取按钮文本,使用setText()设置文本

事实上,QPushButton的核心功能都是QAbstractButton提供的,自身提供的属性都比较简单。其中,default和audoDefault影响的是按下enter时,点击那个按钮的行为,flat把按钮设置为扁平的样式


带有图标的按钮

(1)创建 resource.qrc 文件并导入图片

具体操作步骤参见 上一篇的QWidget 中的windowIcon部分

(2)在界面上创建一个按钮

(3)修改 widget.cpp,给按钮设置图标

(4)执行程序

观察结果:


2、Radio Button

带有快捷键的按钮

(1)在界面中拖五个按钮

五个按钮的 objectName 分别为 pushButton_target、pushButton_up、pushButton_down、pushButton_left、pushButton_right。

(2)创建 resource.qrc,并导入 5 个图片

(3)修改 widget.cpp,设置图标资源和快捷键
使用 setShortcut 给按钮设置快捷键,参数是⼀个 QKeySequence 对象,表示一个按键序列,支持持组合键(Ctrl + C 这种)。
QKeySequence 的构造函数参数,可以直接使用 "Ctrl + C" 这样的按键名字符串表示,也可以使用预定义好的常量(形如 Qt::CTRL + Qt::Key_C)表示。


(4)修改 widget.cpp,设置四个方向键的 slot 函数

(5)运行程序

此时点击按钮,或者使用 wasd 均可让 “柯南” 移动:


按钮的重复触发

在上述案例中按住快捷键,是可以进行重复触发的,但是鼠标点击则不能。

(1)修改 widget.cpp,在构造函数中开启重复触发

此时按住鼠标时,即可让 “柯南” 连续移动。


3、Check Box

QCheckBox 表示复选按钮,可以允许选中多个。和 QCheckBox 最相关的属性也是 checkable 和 checked,都是继承自 QAbstractButton。

至于 QCheckBox 独有的属性 tristate 用来实现 “三态复选框”,这个东西比较冷门,这里暂时不讲述。


获取复选按钮的取值

(1)在界面上创建三个复选按钮和一个普通按钮

objectName 分别为 checkBox_study、checkBox_game、checkBox_work 以及 pushButton

(2)给 pushButton 添加 slot 函数

(3)运行程序

可以看到点击确认按钮时,就会在控制台中输出选中的内容:


4、Tool Button

QToolButton 的大部分功能和 QPushButton 是一致的,但 QToolButton 主要应用在工具栏、菜单等场景。


二、显示类控件

1、Label

QLabel 可以用来显示文本和图片。

核心属性如下:

显示不同格式的文本

(1)在界面上创建三个 QLabel

尺存放大一些,objectName 分别为 label、label_2、label_3

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

(3)运行程序

显示图片

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

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

(2)创建 resource.qrc 文件,并把图片导入到 qrc 中

(3)修改 widget.cpp,给 QLabel 设置图片

这个图片本身的尺寸是 1280 * 150,超出了窗口的大小(800 * 800)。

执行程序,观察结果:

(4)修改代码,设置 scaledContents 属性

再次运行程,观察效果,可以看到图片已经被拉伸,可以把窗口填满了:

此时,如果拖动窗口大小,可以看到图片并不会随着窗口大小的改变而同步变化。

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

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

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

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

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


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

(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 设置属性

(3)运行程序


设置伙伴

(1)创建两个 label 和 两个 radioButton

objectName 分别为 label、label_2、radioButton、radioButton_2

此处把 label 中的文本设置为 “快捷键 &A” 这样的形式。其中 & 后面跟着的字符就是快捷键,可以通过 alt + A 的方式来触发该快捷键。但是注意,这里的快捷键和 QPushButton 的不同需要搭配 alt 和 单个字母的方式才能触发。

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


(2)编写 widget.cpp,设置 buddy 属性

这里也可以使用Qt Designer直接设置:

(3)运行程序

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

2、LCD Number

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

核心属性:

倒计时

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

objectName 为 lcdNumber

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


(3)修改 widget.cpp,在构造函数中初始化 QTimer
QTimer 表示定时器,通过 start 方法启动定时器之后,就会每隔一定周期触发一次 QTimer::timeout 信号
使用 connect 把 QTimer::timeout 信号和 Widget::updateTime 连接起来,意味着每次触发 QTimer::timeout 都会执行 Widget::updateTime


(4)修改 widget.cpp,实现 handle

  • 通过 intValue 获取到 QLCDNumber 内部的数值。

  • 如果 value 的值归 0 了,就停止 QTimer,接下来 QTimer 也就不会触发 timeout 信号了。

(5)执行程序

可以看到每隔一秒钟,显示的数字就减少 1:

(6)针对上述代码,存在两个问题

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

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

B. 上述代码如果是在 Widget 构造函数中,另起一个线程,在新线程中完成循环 + sleep 是否可以呢?

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

这样的约定主要是因为 GUI 中的状态往往是牵一发动全身的,修改一个地方,就需要同步的对其他内容进行调整。比如调整了某个元素的尺存,就可能影响到内部的文字位置,或者其他元素的位置。这里一连串的修改都是需要按照一定的顺序来完成的。

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

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

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


3、ProgressBar

使用QProgressBar表示一个进度条

核心属性:


设置进度条按时间增长

(1)在界面上创建进度条,objectName 为 progressBar

其中最小值设为 0,最大值设为 100,当前值设为 0:

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

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

上述问题其实是通过 Qt 内部提供的一个特殊技巧来实现的。在 Qt 中有一个专门的头文件(#include <QWidget>),这个头文件中包含了 Qt 中所有类的 “前置声明”(class QWidget,class QPushButton,class QTimer)。这个头文件我们一般不会直接接触到,但是包含其它的 Qt 的头文件,都会间接的包含到这个头文件。

如果 Widget 类的前面以及提供了 QTimer 类的声明的话,此时就可以在 Widget 中声明 QTimer 的指针 / 引用类型的成员。后续如果要真正使用 QTimer 的头文件(包括创建实例,使用里面的成员),仍然要包含 QTimer 的头文件(包含了 QTimer 的详细的类的定义)。

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

主要解决的是编译速度的问题。C/C++ 代码,编译速度在其他语言横向对比中是非常慢的。C++ 编译速度慢和 #include 头文件有直接关系。由于 include 关系错综复杂,所以尽可能减少 include 头文件的个数就可以有效地减少编译时间。

Qt 中就使用 class 前置声明的方式来尽量减少头文件的包含。通过前置声明的方式,Qt 中每个头文件包含的其它头文件数量都能得到一定的降低。


(3)修改 widget.cpp,初始化 QTimer

此处设置 100ms 触发一次 timeout 信号,也就是⼀秒钟触发 10 次

(4)修改 widget.cpp,实现 handle

(5) 运行程序

可以看到进度条中的进度在快速增长:

在实际开发中,进度条的取值往往是根据当前任务的实际进度来进行设置的。比如需要读取一个很大的文件,就可以获取文件的总的大小和当前读取完毕的大小,来设置进度条的比例。

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

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


创建一个红色的进度条

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

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


(1)在界面上创建一个进度条

(2)在 Qt Designer 右侧的属性编辑器中找到 QWidget 的 styleSheet 属性

编辑内容:其中的 chunk 是选中进度条中的每个 “块”,使用 QProgressBar::text 则可以选中文本。

同时把 QProcessBar 的 alignment 属性设置为垂直水平居中:

此处如果不设置 alignment,进度条中的数字会跑到左上角。

(3)执行程序

可以看到如下效果,就得到了一个红色的进度条:

通过上述方式,也可以修改文字的颜色,字体大小等样式。


4、Calendar Widget

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

核心属性:

重要信号:

获取选中的日期

(1)在界面上创建一个 QCalendarWidget 和一个 label

objectName 为 calendarWidget,label

(2)给 QCalendarWidget 添加 slot 函数

(3)执行程序

可以看到当选择不同的日期时,label 中的内容就会随之改变:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 15:49:09

论文降AI率10个常见问题解答,轻松把AI率压到个位数

又是一年毕业季&#xff0c;论文AIGC检测已经成为答辩前绕不开的关卡&#xff0c;不少同学都在为AI率超标头疼。今天就整理了降AI过程中大家问得最多的10个问题&#xff0c;3分钟帮你搞懂AI率过高的原因&#xff0c;掌握实用的降AI技巧&#xff0c;轻松通过AIGC检测。 1、论文…

作者头像 李华
网站建设 2026/5/8 15:49:06

Semicon West 2012深度解析:从450mm晶圆到EUV光刻的产业转折点

1. 从一场行业盛会看半导体制造的脉搏&#xff1a;Semicon West 2012现场纪实与深度解析如果你在半导体行业里待过几年&#xff0c;那么“Semicon West”这个名字对你来说&#xff0c;绝不仅仅是一个展会。它更像是一年一度的行业“体检”和“风向标”。2012年7月&#xff0c;第…

作者头像 李华
网站建设 2026/5/8 15:48:06

生物标志物筛选的相关研究与技术

生物标志物是指能反映生物体内生理状态、病理变化或对药物干预反应的可检测分子&#xff0c;包括蛋白质、核酸、代谢物、细胞因子等&#xff0c;其大量筛选是现代生物医学研究与临床应用的核心环节之一。在肿瘤、免疫、代谢、神经等热门研究领域及相关疾病中&#xff0c;生物标…

作者头像 李华
网站建设 2026/5/8 15:46:50

基于PyAutoGUI与图像识别的微信自动化工具OpenClawWeChat实战指南

1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目&#xff0c;叫hillghost86/OpenClawWeChat。乍一看这个名字&#xff0c;可能有点摸不着头脑&#xff0c;但如果你对微信生态、自动化工具或者RPA&#xff08;机器人流程自动化&#xff09;感兴趣&#xff0c;那这个项目…

作者头像 李华