Qt常用控件-> 1、概述、QWidget核心属性
一、控件概述
Widget是Qt中的核心概念,英文原意是”小部件“,此处也把它翻译为”控件“。控件是构成一个图形化界面的基本要素

像上述示例中的按钮、列表视图、树形视图、单行输入框、多行输入框、滚动条、下拉框都可以称为”控件“
Qt作为一个成熟的GUI开发框架,内置了大量的常用控件。这一点在Qt Designer中就可以看出来,并且Qt也提供了“自定义控件”的能力,可以让我们在现有控件不能满足需求的时候,对现有控件做出扩展,或者手搓新的控件。

所以,学习Qt其中一个重要的任务就是熟悉并且掌握Qt内置的常用控件,这些控件对于我们快速开发出符合需求的界面是至关重要的
1、关于控件体系的发展
(1)第一阶段
完全没有控件。此时需要通过一些绘图API手动的绘制出按钮或者输入框等内容,代码编写繁琐。

图中的文曲星就是Lava平台开发
(2)第二阶段
只包含粗略的控件。只是提供了按钮、输入框、单选框、复选框等最常用的控件。

图中html的原生控件
(3)第三阶段
更完整的控件体系,基本可以覆盖到GUI开发中的大部分场景。(例如早期的 MFC、VB、C++ Builder、Qt、Delphi、后来的 Android SDK、Java FX、前端的各种 UI 库等)

上图是前端中的 Element-ui 中的控件概览,无论是丰富程度还是颜值,都比 Qt 自带的控件更胜一筹。
二、QWidget核心属性
在Qt中,使用QWidget类表示“控件”,像按钮、视图、输入框、滚动条等具体的控件类,都是继承自QWidget。QWidget中包含了整个控件体系中通用的部分
在Qt Designer中,随便拖一个控件过来,选中该控件,即可在右下方可以看到QWidget中的属性。

这些属性既可以通过Qt Designer直接修改,也可以通过代码的方式修改。这些属性的具体含义在Qt Assistant中均有详细介绍
在Qt Assistant中搜索QWidget,即可找到对应的文档说明(或者在 Qt Creator 代码中选中 QWidget,按 F1(+Fn) 也可)
1、核心属性概览



下面我们只会介绍其中一些重要和常用的属性
2、enabled

所谓“禁用”指的是该控件不能接受任何用户的输入事件,并且外观上往往是灰色的。如果一个widget被禁用,则该widget的子元素也被禁用。
使用代码创建一个禁用状态的按钮:

运行程序,可以看到按钮处于灰色状态,无法被点击:

通过按钮2切换到按钮1的禁用状态
1、使用Qt Designer拖两个按钮到Widget中

两个按钮的objectName分别为pushButton和pushButton_2。
QObject的objectName属性介绍;
QObject是QWidget的父类,里面最主要的属性就是objectName。在一个Qt程序中,objectName相当于对象的身份标识,彼此之间不能重复。
在使用Qt Designer时,尤其是界面上存在多个Widget的时候,可以通过object获取到指定的widget对象
Qt Designer 生成的ui文件,本身是xml格式的,qmake会把这个xml文件转换成C++的.h文件(这个文件生成在build目录中),构成一个ui_widget类。
每个widget的objectName最终就会成为ui_widget类的属性名字。最终这个类的实例就是:ui::Widget *ui,因此就可以通过形如ui_pushButton或者ui->pushButton_2这样的代码获取到界面上的widget对象了
当前自动生成的objectName是有规律的:控件的类型+下划线+数字。很明显,以数字的方式命名并不是一个好的编程习惯,这里我将它修改为如下所示:

(2)生成两个按钮的slot函数
使用isEnabled获取当前按钮的可用状态
使用setEnabled修改按钮的可用状态,此处是直接针对原来的可用状态进行取反后设置

运行程序可以看到:初始情况下,上面的按钮是可用状态

接着点击下方按钮,即可使上方按钮被禁用

再次点击下方按钮,上方按钮就会解除禁用(禁用状态的按钮为灰色,且不可点击)

在Qt Designer中创建按钮的时候可用设置按钮的初始状态是“可用”还是”禁用“。如果把enabled这一列的对勾去掉,则按钮的初始状态就是“禁用状态”

3、geometry
位置和尺寸是四个属性的统称:
- x横坐标
- y纵坐标
- width宽度
- height高度

但是实际开发中并不会直接使用这几个属性,而是通过一系列封装的方法来获取/修改
对于Qt的坐标系,不要忘记是一个”左手坐标系“,其中坐标系的远点是当前元素的父元素的左上角


控制按钮的位置
(1)在界面中拖五个按钮
五个按钮的objectName分别为:pushButton_target、pushButton_up、pushButton_down、pushButton_left、pushButton_right

(2)在widget.cpp中编写四个按钮的slot函数

运行程序可以看到:按下下方的四个按钮就会控制target的左上角位置,对应的按钮整个尺寸也会发生改变
上述代码是直接设置的QRect中的x和y。实际上,QRect内部是存储了左上和右下两个点的坐标,再通过这两个点的坐标差值计算长宽。单纯修改左上坐标就会引起整个矩形的长宽发生改变

如果想让整个按钮都移动(宽度和高度不会发生改变),可以不再修改QRect,而是通过QRect基于setGeometry第二个版本的函数重新设置位置即可:

geometry和frameGeometry的区别
(1)在按钮的slot函数中编写代码&在构造函数中也添加同样的代码

(2)执行程序
可以看到:在构造函数中打印的geometry和frameGeometry是相同的。但是在点击按钮时,打印的geometry和farmeGrometry则存在差异

注意:在构造方法中,Widget刚刚创建出来,还没有加入到对象树中,此时也就不具备Window frame。在按钮的slot函数中,由于用户点击的时候,对象已经构造好了,此时Widget已经具备了Window frame,因此在位置和尺寸上均出现了差异。
如果上述代码修改成打印pushButton的geometry和frameGeometry,结果就是完全相同的。因为pushButton并非是一个窗口
4、window Title

注意:上述设置操作针对不同的widget可能会有不同的行为
如果是顶层widget(独立窗口),这个操作才会有效
如果是子widget,这个操作无任何效果
设置窗口标题
(1)修改widget.cpp

执行效果:

5、windowlcon

同 windowTitle,上述操作仅针对顶层 widget 有效。
(1)设置窗口图标
A.现在D盘中保存一张图片,我这里命名为Q&A.jpg

B.修改widget.cpp
前面推荐使用堆来创建对象,主要是因为要确保当前控件的生命周期是足够的,要通过Qt对象树来释放对象
QIcon自身是一个比较小的对象。创建出来之后,就是要设置到某个QWidget里面,QIcon对象本身是否释放并不影响图标最终的显示。
QIcon也不支持对象树,无法给他执行父对象

注意:Windows 下路径的分隔符可以使用 / 也可以使用 \,但是如果在字符串中使用 \,需要写作转义字符的形式 \\,因此还是更推荐使用 /。
C.运行程序
可以看到窗口图标已经成为上述图片

于此同时,程序在任务栏中的图标也发生改变:

实际开发中,一般不会在代码中通过绝对路径去引入图片。因为我们无法保证程序发布后,用户的电脑上也有同样的路径。如果使用相对路径,则需要确保代码中的相对路径写法和图片实际所在的路径匹配(比如代码中写作“/image/Q&A.jpg”)
- 绝对路径:以盘符(window)或者以/(Linux)开头的路径
- 相对路径:以. (表示当前路径)或者以..(表示当前路径上级路径)开头的路径。其中,经常也会省略,相对路径的前提是需要明确“当前工作目录”。
对于Qt程序来说,当前工作目录可能是变化的。比如通过Qt Create运行的程序,当前工作目录是项目的构建目录,直接双击exe运行,工作目录则是exe所在目录
所谓构建目录,是和Qt项目并列的,专门用来放生成的临时文件和最终exe的目录

Qt使用qrc机制帮我们自动完成了上述工作,更方便的来管理项目依赖的静态资源。这个机制可以从根本上解决以下两个问题:
- 确保我们的图片所在路径在目标用户机器上存在
- 确保我们的图片不会被用户搞没了
qrc文件是一种XML格式的资源配置文件,它用XML记录硬盘上的文件和对应的随意指定的资源名称,应用程序通过资源名程来访问这些资源。在Qt开发中,可以通过将资源文件添加到项目中来方便地访问和管理这些资源,这些资源文件可以位于qrc文件所在目录的统计或其子目录下。
在构建程序的过程中,Qt会把资源文件的二进制数据转成cpp代码,编译到exe中,从而便依赖的资源变得“路径无关”
这种资源管理机制并非Qt独有,很多开发框架都有类似的机制。例如:Android的Resources和AssetManager也是类似的效果
qrc的缺点:无法导入太大的资源文件
通过qrc管理图片作为图标
(1)右键项目,创建一个Qt Resource File(qrc文件)

文件名随意起(不要带中文和特殊符号即可),这里叫做:resource.qrc


(2)在 qrc 编辑器中添加前缀

此处我们前缀设置成 / 即可。所谓的前缀,可以理解成 “虚拟的目录”,这个目录在我们的电脑中并不是真实存在的,是 Qt 自己抽象出来的,它决定了后续我们如何在代码中访问资源。
(3)在资源编辑器中,点击 add Files 添加资源文件
此处我们需要添加的是:Q&A.jpg:


注意 :添加的文件必须是在 qrc 文件的同级目录或者同级目录的子目录中,因此我们需要把之前 D 盘中的 Q&A.jpg 复制到上述目录中。
添加完毕后,可以在资源编辑器中看到添加好的文件:

(4)在代码中使用 Q&A.jpg
A.编辑widget.cpp

代码中需要访问 qrc 中管理的文件时,就需要在路径上带有 : 前缀。创建的前缀叫什么名字,代码中就写什么名字:前缀 + 文件名。
注意上述路径的访问规则:
使用 : 作为开头,表示从 qrc 中读取资源
/ 是上面配置的前缀
rose.jpg 是资源的名称
需要确保代码中编写的路径和添加到 qrc 中资源的路径匹配,否则资源无法被访问(同时也不会有报错提示)。
(5)运行程序
可以看到图标已经能正确设置:

我们可以进入到项目的构建目录中可以看到:目录中多了一个 qrc_resource.cpp 文件,直接打开这个文件可以看到:

qrc 中导入的图片资源会被转成这个 qrc_resource.cpp(自动生成)这个 c++ 代码:


上述代码其实就是通过 unsigned char 数组,把 rose.jpg 中的每个字节都记录下来。这些代码会被编译到 exe 中,后续无论 exe 被复制到哪个目录下都确保能够访问到该图片资源。
上述 qrc 这一套资源管理方案的优点和缺点都很明显:
- 优点:确保了图片、字体、剩余等资源能够真正做到 “目录无关”,无论如何都不会出现资源丢失的情况。
- 缺点:不适合管理体积大的资源。如果资源比较大(比如是几个 MB 的文件),或者资源特别多,生成的最终的 exe 体积就会比较大,程序运行消耗的内存也会增大,程序编译的时间也会显著增加。
6、windowOpacity

调整窗口透明度
(1)在界面上拖放两个按钮,分别用来增加不透明度
objectName分别为PushButton_add和PushButton_sub;

(2)编写 wdiget.cpp, 编写两个按钮的 slot 函数
- 点击 pushButton_sub 会减少不透明度,也就是窗口越来越透明
- 点击 pushButton_add 会增加不透明度,窗口会逐渐恢复

7、cursor

在 Qt Designer 中设置按钮的光标
(1)在界面中创建一个按钮

(2)直接在右侧属性编辑区修改 cursor 属性为 “打开手势”

(3)运行程序
鼠标悬停到按钮上,即可看到光标的变化。
通过代码设置按钮的光标
(1) 编写 widget.cpp
其中 Qt::WaitCursor 就是自带的沙漏 / 转圈形状的光标。

系统内置的光标形状如下:
Ctrl + 左键点击 Qt::WaitCursor 跳转到源码即可看到:

自定义鼠标光标
Qt 自带的光标形状有限,我们也可以自己找个图片,做成鼠标的光标。比如我的 “男神懒羊羊”。

(1)创建 qrc 资源文件,添加前缀 /,并加入 huaji.png


(2)编写 widget.cpp

8、front

关于 QFont:

在 Qt Designer 中设置字体属性
(1)在界面上创建一个 label

(2)在右侧的属性编辑区,设置该 label 的 font 相关属性
在这里调整上述属性,可以实时的看到文字的变化。

(3)执行程序

在代码中设置字体属性
(1)编写 widget.cpp

(2)运行程序

在实际开发中,字体属性如何选择是一个 “审美问题”,而不是 “技术问题”,往往需要有一定的艺术细胞。幸运的是,公司中往往有专业的 “美工” / “设计” 这样的岗位,去做这方面的工作,我们程序员只要按照人家给的设计稿,把代码写出来即可,不必过多考虑怎样搭配才好看的问题。
9、toolTip

oolTip 只是给用户看的,在代码中一般不需要获取到 toolTip。
设置按钮的 toolTip
(1)在界面上拖放两个按钮:objectName 设置为 pushButton_yes 和 pushButton_no

(2)编写 widget.cpp

(3)运行程序
观察效果,可以看到鼠标停到按钮上之后,就能弹出提示,时间到后自行消失。

10、focusPolicy
设置控件获取到焦点的策略,比如某个控件能否用鼠标选中或者能否通过 tab 键选中。
所谓 “焦点”,指的就是能选中这个元素。接下来的操作(比如键盘操作),就都是针对该焦点元素进行的了。这个对于输入框、单选框、复选框等控件非常有用的。
这个事情就和 war3 或者 sc2 中,先选中单位,再下达命令是一样的。



- Qt::FocusPolicy 是一 个 枚举 类型,取值如下:
- Qt::NoFocus:控件不会接收键盘焦点
- Qt::TabFocus:控件可以通过 Tab 键接收焦点
- Qt::ClickFocus:控件在鼠标点击时接收焦点
- Qt::StrongFocus:控件可以通过 Tab 键和鼠标点击接收焦点(默认值)
- Qt::WheelFocus:类似于 Qt::StrongFocus,同时控件也通过⿏标滚轮获取到焦点(新增的选项, ⼀般很少使用)
理解不同的 focusPolicy
(1)在界面上创建四个单行输入框(Line Edit)

(2)修改四个输入框的 focusPolicy 属性为 Qt::StrongFocus(默认取值,一般不用额外修改)

此时运行程序可以看到,使用鼠标单击 / tab,就可以移动光标所在输入框,从而接下来的输入就是针对这个获取焦点的输⼊框展开的了。
(3)修改第二个输入框的 focusPolicy 为 Qt::NoFocus,则第二个输入框不会被 tab / 鼠标左键选中

(4)修改第二个输入框 focusPolicy 为 Qt::TabFocus,则只能通过 tab 选中,无法通过鼠标选中

(5)修改第二个输入框 focusPolicy 为 Qt::ClickFocus,则只能通过 tab 选中,无法通过鼠标选中

11、styleSheet
通过 CSS 设置 widget 的样式。
CSS(Cascading Style Sheets 层叠样式表)本身属于网页前端技术,主要就是用来描述界面的
样式。所谓 “样式”,包括不限于大小、位置、颜色、间距、字体、背景、边框等。我们平时看到的丰富多彩的网页就都会用到大量的 CSS。
Qt 虽然是做 GUI 开发,但实际上和网页前端有很多异曲同工之处,因此 Qt 也引入了对于 CSS 的支持。CSS 中可以设置的样式属性非常多,基于这些属性 Qt 只能支持其中一部分,称为 QSS(Qt Style Sheet)。具体的支持情况可以参考 Qt 文档中 "Qt Style Sheets Reference" 章节。
设置文本样式
(1)在界面上创建 label

(2)编辑右侧的 styleSheet 属性,设置样式

或者选择下面这种方式打开:


此处的语法格式同 CSS,使用键值对的方式设置样式。其中键和值之间使用 : 分割.,键值对之间使用 ; 分割。
另外,Qt Designer 只能对样式的基本格式进行校验,不能检测出哪些样式不被 Qt ⽀持,比如 text-align: center 这样的文本居中操作,就无法支持。
编辑完成样式之后,可以看到在 Qt Designer 中能够实时预览出效果:

(3)运⾏程序
可以看到实际效果和预览效果基本一致:

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)