控件概述
Widget 是 Qt 中的核⼼概念. 英⽂原义是 “⼩部件”, 我们此处也把它翻译为"控件" .
控件是构成⼀个图形化界⾯的基本要素.
Qt 作为⼀个成熟的 GUI 开发框架, 内置了⼤量的常⽤控件. 这⼀点在 Qt Designer 中就可以看到端倪.
并且 Qt 也提供了 “⾃定义控件” 的能⼒, 可以让程序猿在现有控件不能满⾜需求的时候, 对现有控件做
出扩展, 或者⼿搓出新的控件.
QWidget 核⼼属性
在 Qt 中, 使⽤ QWidget 类表⽰ “控件”. 像按钮, 视图, 输⼊框, 滚动条等具体的控件类, 都是继承⾃QWidget.
可以说, QWidget 中就包含了 Qt 整个控件体系中, 通⽤的部分.
在 Qt Designer 中, 随便拖⼀个控件过来, 选中该控件, 即可在右下⽅看到 QWidget 中的属性
这些属性既可以通过 QtDesigner 会直接修改, 也可以通过代码的⽅式修改.
这些属性的具体含义, 在 Qt Assistant 中均有详细介绍.
核⼼属性概览
下列表格列出了 QWidget 中的属性及其作⽤.
属性 | 作⽤ |
---|---|
enabled | 设置控件是否可使⽤. true 表⽰可⽤, false 表⽰禁⽤. |
geometry | 位置和尺⼨. 包含 x, y, width, height 四个部分.其中坐标是以⽗元素为参考进⾏设置的. |
windowTitle | 设置 widget 标题 |
windowIcon | 设置 widget 图标 |
windowOpacity | 设置 widget 透明度 |
cursor | ⿏标悬停时显⽰的图标形状.是普通箭头, 还是沙漏, 还是⼗字等形状.在 Qt Designer 界⾯中可以清楚看到可选项. |
font | 字体相关属性.涉及到字体家族, 字体⼤⼩, 粗体, 斜体, 下划线等等样式. |
toolTip | ⿏标悬停在 widget 上会在状态栏中显⽰的提⽰信息. |
toolTipDuring | toolTip 显⽰的持续时间. |
statusTip | Widget 状态发⽣改变时显⽰的提⽰信息(⽐如按钮被按下等). |
whatsThis | ⿏标悬停并按下 alt+F1 时, 显⽰的帮助信息(显⽰在⼀个弹出的窗⼝中). |
styleSheet | 允许使⽤ CSS 来设置 widget 中的样式.Qt 中⽀持的样式⾮常丰富, 对于前端开发⼈员上⼿是⾮常友好的. |
enabled
API | 说明 |
---|---|
isEnabled() | 获取到控件的可⽤状态. |
setEnabled | 设置控件是否可使⽤. true 表⽰可⽤, false 表⽰禁⽤. |
代码⽰例: 使⽤代码创建⼀个禁⽤状态的按钮
代码⽰例: 通过按钮2 切换按钮1 的禁⽤状态.
-
使⽤ Qt Designer 拖两个按钮到 Widget 中.
两个按钮的 objectName 分别为 pushButton 和 pushButton_2 -
⽣成两个按钮的 slot 函数.
使⽤ isEnabled 获取当前按钮的可⽤状态.
使⽤ setEnabled 修改按钮的可⽤状态. 此处是直接针对原来的可⽤状态进⾏取反后设置.
运⾏程序, 可以看到, 初始情况下, 上⾯的按钮是可⽤状态.
点击下⽅按钮, 即可使上⽅按钮被禁⽤; 再次点击下⽅按钮, 上⽅按钮就会解除禁⽤. (禁⽤状态的按钮为灰⾊, 且不可点击).
geometry
位置和尺⼨. 其实是四个属性的统称:
- x 横坐标
- y 纵坐标
- width 宽度
- height ⾼度
但是实际开发中, 我们并不会直接使⽤这⼏个属性, ⽽是通过⼀系列封装的⽅法来获取/修改
API | 说明 |
---|---|
geometry() | 获取到控件的位置和尺⼨. 返回结果是⼀个 QRect, 包含了 x, y, width, height. 其中 x, y 是左上⻆的坐标. |
setGeometry(QRect);setGeometry(int x, int y, int width, int height) | 设置控件的位置和尺⼨. 可以直接设置⼀个 QRect, 也可以分四个属性单独设置. |
代码⽰例: 控制按钮的位置
-
在界⾯中拖五个按钮.
五个按钮的 objectName 分别为 pushButton_target , pushButton_up ,
pushButton_down , pushButton_left , pushButton_right五个按钮的初始位置和⼤⼩都随意.
-
在 widget.cpp 中编写四个按钮的 slot 函数
运⾏程序, 可以看到, 按下下⽅的四个按钮, 就会控制 target 的左上⻆的位置. 对应的按钮整个尺⼨也会发⽣改变.
上述代码中我们是直接设置的 QRect 中的 x, y . 实际上 QRect 内部是存储了左上和右下两个点的坐标, 再通过这两个点的坐标差值计算⻓宽.
单纯修改左上坐标就会引起整个矩形的⻓宽发⽣改变.
如果想让整个按钮都移动, 可以改成下列代码:
代码⽰例: ⼀个表⽩程序
-
往界⾯上拖拽两个按钮和⼀个 Label.
Label 的 objectName 为 pushButton_accept 和 pushButton_reject , label 的objectName 为 label
控件中⽂本如下图所⽰
-
在 widget.cpp 中添加 slot 函数.
运⾏程序, 可以看到, 当点击 “NO” 时, 按钮就跑了
上述代码使⽤的是 pressed, ⿏标按下事件. 如果使⽤ mouseMoveEvent, 会更狠⼀些, 只要⿏标移动过来, 按钮就跑了.
对应的代码更⿇烦⼀些 (需要⾃定义类继承⾃ QPushButton, 重写 mouseMoveEvent ⽅法). 此处暂时不展开.
window frame 的影响
如果 widget 作为⼀个窗⼝ (带有标题栏, 最⼩化, 最⼤化, 关闭按钮), 那么在计算尺⼨和坐标的时候就有两种算法. 包含 window frame 和 不包含 window frame.
其中 x(), y(), frameGeometry(), pos(), move() 都是按照包含 window frame 的⽅式来计算的.
其中 geometry(), width(), height(), rect(), size() 则是按照不包含 window frame 的⽅式来计算的.
当然, 如果⼀个不是作为窗⼝的 widget , 上述两类⽅式得到的结果是⼀的.
相关 API
API | 说明 |
---|---|
x() | 获取横坐标计算时包含 window frame |
y() | 获取纵坐标计算时包含 window frame |
pos() | 返回 QPoint 对象, ⾥⾯包含 x(), y(), setX(), setY() 等⽅法.计算时包含 window frame |
frameSize() | 返回 QSize 对象, ⾥⾯包含 width(), height(), setWidth(), setHeight() 等⽅法.计算时包含 window frame |
frameGeometry() | 返回 QRect 对象. QRect 相当于 QPoint 和 QSize 的结合体. 可以获取 x, y,width, size.计算时包含 window frame 对象. |
width() | 获取宽度计算时不包含 window frame |
height() | 获取⾼度计算时不包含 window frame |
size() | 返回 QSize 对象, ⾥⾯包含 width(), height(), setWidth(), setHeight() 等⽅法.计算时不包含 window frame |
rect() | 返回 QRect 对象. QRect 相当于 QPoint 和 QSize 的结合体. 可以获取并设置 x,y, width, size.计算时不包含 window frame 对象. |
geometry() | 返回 QRect 对象. QRect 相当于 QPoint 和 QSize 的结合体. 可以获取 x,y,width, size.计算时不包含 window frame 对象. |
setGeometry() | 直接设置窗⼝的位置和尺⼨. 可以设置 x, y, width, height, 或者 QRect 对象.计算时不包含 window frame 对象. |
代码⽰例: 感受 geometry 和 frameGeometry 的区别.
-
在界⾯上放置⼀个按钮.
-
在按钮的 slot 函数中, 编写代码
-
在构造函数中, 也添加同样的代码
执⾏程序, 可以看到, 构造函数中, 打印出的 geometry 和 frameGeometry 是相同的.
但是在点击按钮时, 打印的 geometry 和 frameGeometry 则存在差异.
windowTitle
API | 说明 |
---|---|
windowTitle() | 获取到控件的窗⼝标题. |
setWindowTitle(const QString& title) | 设置控件的窗⼝标题. |
代码⽰例: 设置窗⼝标题
执⾏效果
windowIcon
API | 说明 |
---|---|
windowIcon() | 获取到控件的窗⼝图标. 返回 QIcon 对象. |
setWindowIcon(constQIcon& icon) | 设置控件的窗⼝图标. |
代码⽰例: 设置窗⼝图标
-
先在 F 盘中放⼀个图⽚, 名字为 rose.jpg
-
修改 widget.cpp
-
运⾏程序, 可以看到窗⼝图标已经成为上述图⽚;于此同时, 程序在任务栏中的图表也发⽣改变
对于 Qt 程序来说, 当前⼯作⽬录可能是变化的. ⽐如通过 Qt Creator 运⾏的程序, 当前⼯作⽬录是项⽬的构建⽬录; 直接双击 exe 运⾏, ⼯作⽬录则是 exe 所在⽬录.
所谓构建⽬录, 是和 Qt 项⽬并列的, 专⻔⽤来放⽣成的临时⽂件和最终 exe 的⽬录.
代码⽰例: 获取当前的⼯作⽬录
-
在界⾯上创建⼀个⽐较⼤的 label, 确保能把路径显⽰完整. objectName 使⽤默认的 label 即可
-
修改 widget.cpp
使⽤ QDir::currentPath() 即可获取到当前⼯作⽬录
-
直接在 Qt Creator 中执⾏程序, 可以看到当前⼯作⽬录是项⽬的构建⽬录.
Qt 使⽤ qrc 机制帮我们⾃动完成了上述⼯作, 更⽅便的来管理项⽬依赖的静态资源.
代码⽰例: 通过 qrc 管理图⽚作为图标
-
右键项⽬, 创建⼀个 Qt Resource File (qrc ⽂件), ⽂件名随意起(不要带中⽂), 此处叫做resource.qrc .
-
在 qrc 编辑器中, 添加前缀.
此处我们前缀设置成 / 即可.(所谓的前缀, 可以理解成 “⽬录” . 这个前缀决定了后续我们如何在代码中访问资源) -
在 资源编辑器 中, 点击 add Files 添加资源⽂件. 此处我们需要添加的是 myimg.jpg
添加的⽂件必须是在 qrc ⽂件的同级⽬录, 或者同级⽬录的⼦⽬录中. 因此我们需要把之前 F 盘中的 myimg.jpg 复制到上述⽬录中. -
在代码中使⽤ myimg.jpg
编辑 widget.cpp
注意上述路径的访问规则.
使⽤ : 作为开头, 表⽰从 qrc 中读取资源.
/ 是上⾯配置的前缀
myimg.jpg 是资源的名称
需要确保代码中编写的路径和添加到 qrc 中资源的路径匹配. 否则资源⽆法被访问 -
运⾏程序, 可以看到图标已经能正确设置
windowOpacity
API | 说明 |
---|---|
windowOpacity() | 获取到控件的不透明数值. 返回 float, 取值为 0.0 -> 1.0 其中 0.0 表⽰全透明, 1.0 表⽰完全不透明. |
setWindowOpacity(float n) | 设置控件的不透明数值. |
代码⽰例: 调整窗⼝透明度
-
在界⾯上拖放两个按钮, 分别⽤来增加不透明度和减少不透明度.
objectName 分别为 pushButton_add 和 pushButton_sub
-
编写 wdiget.cpp, 编写两个按钮的 slot 函数
点击 pushButton_sub 会减少不透明度, 也就是窗⼝越来越透明
点击 pushButton_add 会增加不透明度, 窗⼝会逐渐恢复
-
执⾏程序, 可以看到, 点击了⼏下 - 之后, 就可以透过窗⼝看到后⾯的代码. 点击 + ⼜会逐渐恢复.
同时控制台中也可以看到 opacity 数值的变化
cursor
API | 说明 |
---|---|
cursor() | 获取到当前 widget 的 cursor 属性, 返回 QCursor 对象.当⿏标悬停在该 widget 上时, 就会显⽰出对应的形状. |
setCursor(const QCursor& cursor) | 设置该 widget 光标的形状. 仅在⿏标停留在该 widget 上时⽣效. |
QGuiApplication::setOverrideCursor(const QCursor& cursor | 设置全局光标的形状. 对整个程序中的所有 widget 都会⽣效. 覆盖上⾯的 setCursor 设置的内容. |
代码⽰例: 在 Qt Designer 中设置按钮的光标
-
在界⾯中创建⼀个按钮
-
直接在右侧属性编辑区修改 cursor 属性为 “打开”
-
运⾏程序, ⿏标悬停到按钮上, 即可看到光标的变化.
代码⽰例: 通过代码设置按钮的光标
-
编写 widget.cpp
其中 Qt::OpenHandCursor 就是⾃带的打开形状的光标.
系统内置的光标形状如下:
-
运⾏程序, 观察效果.
代码⽰例: ⾃定义⿏标光标
Qt ⾃带的光标形状有限. 我们也可以⾃⼰找个图⽚, 做成⿏标的光标
-
创建 qrc 资源⽂件, 添加前缀 / , 并加⼊ myimg.jpg
- <