QT常用控件

常用控件

控件概述

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 的禁⽤状态.

  1. 使⽤ Qt Designer 拖两个按钮到 Widget 中.

    两个按钮的 objectName 分别为 pushButton 和 pushButton_2

  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, 也可以分四个属性单独设置.

代码⽰例: 控制按钮的位置

  1. 在界⾯中拖五个按钮.

    五个按钮的 objectName 分别为 pushButton_target , pushButton_up ,

    pushButton_down , pushButton_left , pushButton_right五个按钮的初始位置和⼤⼩都随意.

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

    运⾏程序, 可以看到, 按下下⽅的四个按钮, 就会控制 target 的左上⻆的位置. 对应的按钮整个尺⼨也会发⽣改变.

上述代码中我们是直接设置的 QRect 中的 x, y . 实际上 QRect 内部是存储了左上和右下两个点的坐标, 再通过这两个点的坐标差值计算⻓宽.

单纯修改左上坐标就会引起整个矩形的⻓宽发⽣改变.

如果想让整个按钮都移动, 可以改成下列代码:

代码⽰例: ⼀个表⽩程序

  1. 往界⾯上拖拽两个按钮和⼀个 Label.

    Label 的 objectName 为 pushButton_accept 和 pushButton_reject , label 的objectName 为 label

    控件中⽂本如下图所⽰

  2. 在 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 的区别.

  1. 在界⾯上放置⼀个按钮.

  2. 在按钮的 slot 函数中, 编写代码

  3. 在构造函数中, 也添加同样的代码

执⾏程序, 可以看到, 构造函数中, 打印出的 geometry 和 frameGeometry 是相同的.

但是在点击按钮时, 打印的 geometry 和 frameGeometry 则存在差异.

windowTitle

API 说明
windowTitle() 获取到控件的窗⼝标题.
setWindowTitle(const QString& title) 设置控件的窗⼝标题.

代码⽰例: 设置窗⼝标题

执⾏效果

windowIcon

API 说明
windowIcon() 获取到控件的窗⼝图标. 返回 QIcon 对象.
setWindowIcon(constQIcon& icon) 设置控件的窗⼝图标.

代码⽰例: 设置窗⼝图标

  1. 先在 F 盘中放⼀个图⽚, 名字为 rose.jpg

  2. 修改 widget.cpp

  3. 运⾏程序, 可以看到窗⼝图标已经成为上述图⽚;于此同时, 程序在任务栏中的图表也发⽣改变

对于 Qt 程序来说, 当前⼯作⽬录可能是变化的. ⽐如通过 Qt Creator 运⾏的程序, 当前⼯作⽬录是项⽬的构建⽬录; 直接双击 exe 运⾏, ⼯作⽬录则是 exe 所在⽬录.

所谓构建⽬录, 是和 Qt 项⽬并列的, 专⻔⽤来放⽣成的临时⽂件和最终 exe 的⽬录.

代码⽰例: 获取当前的⼯作⽬录

  1. 在界⾯上创建⼀个⽐较⼤的 label, 确保能把路径显⽰完整. objectName 使⽤默认的 label 即可

  2. 修改 widget.cpp

    使⽤ QDir::currentPath() 即可获取到当前⼯作⽬录

  3. 直接在 Qt Creator 中执⾏程序, 可以看到当前⼯作⽬录是项⽬的构建⽬录.

Qt 使⽤ qrc 机制帮我们⾃动完成了上述⼯作, 更⽅便的来管理项⽬依赖的静态资源.

代码⽰例: 通过 qrc 管理图⽚作为图标

  1. 右键项⽬, 创建⼀个 Qt Resource File (qrc ⽂件), ⽂件名随意起(不要带中⽂), 此处叫做resource.qrc .

  2. 在 qrc 编辑器中, 添加前缀.

    此处我们前缀设置成 / 即可.(所谓的前缀, 可以理解成 "⽬录" . 这个前缀决定了后续我们如何在代码中访问资源)

  3. 在 资源编辑器 中, 点击 add Files 添加资源⽂件. 此处我们需要添加的是 myimg.jpg

    添加的⽂件必须是在 qrc ⽂件的同级⽬录, 或者同级⽬录的⼦⽬录中. 因此我们需要把之前 F 盘中的 myimg.jpg 复制到上述⽬录中.

  4. 在代码中使⽤ myimg.jpg

    编辑 widget.cpp

    注意上述路径的访问规则.

    使⽤ : 作为开头, 表⽰从 qrc 中读取资源.

    / 是上⾯配置的前缀

    myimg.jpg 是资源的名称

    需要确保代码中编写的路径和添加到 qrc 中资源的路径匹配. 否则资源⽆法被访问

  5. 运⾏程序, 可以看到图标已经能正确设置

windowOpacity

API 说明
windowOpacity() 获取到控件的不透明数值. 返回 float, 取值为 0.0 -> 1.0 其中 0.0 表⽰全透明, 1.0 表⽰完全不透明.
setWindowOpacity(float n) 设置控件的不透明数值.

代码⽰例: 调整窗⼝透明度

  1. 在界⾯上拖放两个按钮, 分别⽤来增加不透明度和减少不透明度.

    objectName 分别为 pushButton_add 和 pushButton_sub

  2. 编写 wdiget.cpp, 编写两个按钮的 slot 函数

    点击 pushButton_sub 会减少不透明度, 也就是窗⼝越来越透明

    点击 pushButton_add 会增加不透明度, 窗⼝会逐渐恢复

  3. 执⾏程序, 可以看到, 点击了⼏下 - 之后, 就可以透过窗⼝看到后⾯的代码. 点击 + ⼜会逐渐恢复.

    同时控制台中也可以看到 opacity 数值的变化

cursor

API 说明
cursor() 获取到当前 widget 的 cursor 属性, 返回 QCursor 对象.当⿏标悬停在该 widget 上时, 就会显⽰出对应的形状.
setCursor(const QCursor& cursor) 设置该 widget 光标的形状. 仅在⿏标停留在该 widget 上时⽣效.
QGuiApplication::setOverrideCursor(const QCursor& cursor 设置全局光标的形状. 对整个程序中的所有 widget 都会⽣效. 覆盖上⾯的 setCursor 设置的内容.

代码⽰例: 在 Qt Designer 中设置按钮的光标

  1. 在界⾯中创建⼀个按钮

  2. 直接在右侧属性编辑区修改 cursor 属性为 "打开"

  3. 运⾏程序, ⿏标悬停到按钮上, 即可看到光标的变化.

代码⽰例: 通过代码设置按钮的光标

  1. 编写 widget.cpp

    其中 Qt::OpenHandCursor 就是⾃带的打开形状的光标.

    系统内置的光标形状如下:

  2. 运⾏程序, 观察效果.

代码⽰例: ⾃定义⿏标光标

Qt ⾃带的光标形状有限. 我们也可以⾃⼰找个图⽚, 做成⿏标的光标

  1. 创建 qrc 资源⽂件, 添加前缀 / , 并加⼊ myimg.jpg

  2. 编写 widget.cpp

  3. 运⾏程序, 观察效果

font

API 说明
font() 获取当前 widget 的字体信息. 返回 QFont 对象.
setFont(const QFont& font) 设置当前 widget 的字体信息.

关于 QFont

属性 说明
family 字体家族. ⽐如 "楷体", "宋体", "微软雅⿊" 等.
pointSize 字体⼤⼩
weight 字体粗细. 以数值⽅式表⽰粗细程度取值范围为 [0, 99], 数值越⼤, 越粗
bold 是否加粗. 设置为 true, 相当于 weight 为 75. 设置为 false 相当于weight 为 50
italic 是否倾斜
underline 是否带有下划线
strikeOut 是否带有删除线

代码⽰例: 在 Qt Designer 中设置字体属性

  1. 在界⾯上创建⼀个 label

  2. 在右侧的属性编辑区, 设置该 label 的 font 相关属性

  3. 执⾏程序, 观察效果

代码⽰例: 在代码中设置字体属性

  1. 在界⾯中创建 label, objectName 使⽤默认的 label 即可

  2. 修改 widget.cpp

  3. 运⾏程序, 观察效果

toolTip

API 说明
setToolTip 设置 toolTip.⿏标悬停在该 widget 上时会有提⽰说明.
setToolTipDuring 设置 toolTip 提⽰的时间. 单位 ms.时间到后 toolTip ⾃动消失.

代码⽰例: 设置按钮的 toolTip

  1. 在界⾯上拖放两个按钮. objectName 设置为 pushButton_yes 和 pushButton_no

  2. 编写 widget.cpp

  3. 运⾏程序, 观察效果

    可以看到⿏标停到按钮上之后, 就能弹出提⽰. 时间到后⾃⾏消失

focusPolicy

设置控件获取到焦点的策略. ⽐如某个控件能否⽤⿏标选中或者能否通过 tab 键选中.

所谓 "焦点" , 指的就是能选中这个元素. 接下来的操作 (⽐如键盘操作), 就都是针对该焦点元素进⾏的

了. 这个对于 输⼊框, 单选框, 复选框等控件⾮常有⽤的.

API 说明
focusPolicy() 获取该 widget 的 focusPolicy, 返回 Qt::FocusPolicy.
setFocusPolicy(Qt::FocusPolicy policy) 设置 widget 的 focusPolicy.

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选中.

styleSheet

通过 CSS 设置 widget 的样式

CSS 中可以设置的样式属性⾮常多. 基于这些属性 Qt 只能⽀持其中⼀部分, 称为 QSS (Qt Style Sheet)

具体的⽀持情况可以参考 Qt ⽂档中 "Qt Style Sheets Reference" 章节.

此处只是进⾏⼀个简单的演⽰.

代码⽰例: 设置⽂本样式

  1. 在界⾯上创建 label

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

    此处的语法格式同 CSS, 使⽤键值对的⽅式设置样式. 其中键和值之间使⽤ : 分割. 键值对之间使⽤; 分割.

    编辑完成样式之后, 可以看到在 Qt Designer 中能够实时预览出效果.

  3. 运⾏程序, 可以看到实际效果和预览效果基本⼀致.

代码⽰例: 实现切换夜间模式.

  1. 在界⾯上创建⼀个多⾏输⼊框 (Text Edit) 和两个按钮

    objectName 分别为 pushButton_light 和 pushButton_dark

  2. 编写按钮的 slot 函数

    #333 是深⾊;#fff 是纯⽩⾊;#000 是纯⿊⾊

  3. 运⾏程序, 点击 "⽇间模式", 就是浅⾊背景, 深⾊⽂字; 点击 "夜间模式", 就是深⾊背景, 浅⾊⽂字

按钮类控件

Push Button

使⽤ QPushButton 表⽰⼀个按钮. 这也是当前我们最熟悉的⼀个控件了.

QPushButton 继承⾃ QAbstractButton . 这个类是⼀个抽象类. 是其他按钮的⽗类.

在 Qt Designer 中也能够看到这⾥的继承关系.

QAbstractButton 中, 和 QPushButton 相关性较⼤的属性

属性 说明
text 按钮中的⽂本
icon 按钮中的图标
iconSize 按钮中图标的尺⼨
shortCut 按钮对应的快捷键
autoRepeat 按钮是否会重复触发. 当⿏标左键按住不放时,如果设为 true, 则会持续产⽣⿏标点击事件;如果设为 false, 则必须释放⿏标, 再次按下⿏标时才能产⽣点击事件.(相当于游戏⼿柄上的 "连发" 效果)
autoRepeatDelay 重复触发的延时时间. 按住按钮多久之后, 开始重复触发.
autoRepeatInterval 重复触发的周期

代码⽰例: 带有图标的按钮

  1. 创建 resource.qrc ⽂件, 并导⼊图⽚

  2. 在界⾯上创建⼀个 按钮

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

  4. 执⾏程序, 观察效果

代码⽰例: 带有快捷键的按钮

  1. 在界⾯中拖五个按钮.
    五个按钮的初始位置随意, 其中 pushButton_target 尺⼨设置为 100 * 100, 其余按钮设为 50 *50. ⽂本内容均清空
  2. 创建 resource.qrc , 并导⼊ 5 个图⽚.
  1. 修改 widget.cpp, 设置图标资源和快捷键

    使⽤ setShortcut 给按钮设置快捷键. 参数是⼀个 QKeySequence 对象. 表⽰⼀个按键序列. ⽀持组合键

    QKeySequence 的构造函数参数, 可以直接使⽤ "ctrl+c" 这样的按键名字符串表⽰, 也可以使⽤预定义好的常量表⽰.

  2. 修改 widget.cpp, 设置四个⽅向键的 slot 函数

  3. 运⾏程序, 此时点击按钮, 或者使⽤ wasd 均可让猫咪移动.

代码⽰例: 按钮的重复触发

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

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

此时, 按住⿏标时, 即可让狗头连续移动.

Radio Buttion

QRadioButton 是单选按钮. 可以让我们在多个选项中选择⼀个.

QAbstractButton 中和 QRadioButton 关系较⼤的属性

属性 说明
checkable 是否能选中
checked 是否已经被选中. checkable 是 checked 的前提条件
autoExclusive 是否排他.选中⼀个按钮之后是否会取消其他按钮的选中.对于 QRadioButton 来说默认就是排他的.

代码⽰例: 选择性别

  1. 在界⾯上创建⼀个 label, 和 3 个 单选按钮

    设置的⽂本如下图. 3 个单选按钮的 objectName 分别为 radioButton_male ,radioButton_female , radioButton_other

  2. 修改 widget.cpp, 编辑三个 QRadioButton 的 slot 函数.

  3. 运⾏程序, 可以看到随着选择不同的单选按钮, label 中的提⽰⽂字就会随之变化.

  4. 当前代码中, 如果程序启动, 则不会选择任何选项

    可以修改代码, 让程序启动默认选中性别男

此时运⾏程序, 即可看到 性别男 已经被选中了.

  1. 当前代码中, 也可以禁⽤ "其他" 被选中
    修改 widget.cpp 的构造函数

    运⾏程序, 可以看到, 点击 "其他" 按钮的时候, 虽然不会被选中, 但是可以触发点击事件, 使上⾯的 label显⽰性别为其他.

    使⽤ setEnabled 是更彻底的禁⽤按钮的⽅式. 此时该按钮⽆法被选中, 也⽆法响应任何输⼊

代码⽰例: click, press, release, toggled 的区别

clicked 表⽰⼀次 "点击";pressed 表⽰⿏标 "按下";released 表⽰⿏标 "释放";toggled 表⽰按钮状态切换

  1. 在界⾯上创建四个单选按钮

  2. 给 1 创建 clicked 槽函数, 给 2 创建 pressed 槽函数, 给 3 创建 released 槽函数,给 4 创建 toggled 槽函数.

  3. 运⾏程序, 可以看到

    clicked 是⼀次⿏标按下+⿏标释放触发的.

    pressed 是⿏标按下触发的.

    released 是⿏标释放触发的

    toggled 是 checked 属性改变时触发的

代码⽰例: 单选框分组

  1. 在界⾯上创建 6 个单选框, ⽤来模拟⻨当劳点餐界⾯.

    此时直接运⾏程序, 可以看到, 这六个 QRadioButton 之间都是排他的.

    我们希望每⼀组内部来控制排他, 但是组和组之间不能排他

  2. 引⼊ QButtonGroup 进⾏分组

    修改 widget.cpp

    再次执⾏程序, 可以看到可以按照正确的分组⽅式来完成排他了

Check Box

QCheckBox 表⽰复选按钮. 可以允许选中多个.

和 QCheckBox 最相关的属性也是 checkable 和 checked , 都是继承⾃

QAbstractButton .

代码⽰例: 获取复选按钮的取值

  1. 在界⾯上创建 三个复选按钮, 和⼀个普通按钮

  2. 给 pushButton 添加 slot 函数

  3. 运⾏程序, 可以看到点击确认按钮时, 就会在控制台中输出选中的内容

显⽰类控件

Label

QLabel 可以⽤来显⽰⽂本和图⽚

属性 说明
text QLabel 中的⽂本
textFormat ⽂本的格式.: Qt::PlainText 纯⽂本; Qt::RichText 富⽂本(⽀持 html 标签); Qt::MarkdownText markdown 格式•;Qt::AutoText 根据⽂本内容⾃动决定⽂本格式.
pixmap QLabel 内部包含的图⽚.

代码⽰例: 显⽰不同格式的⽂本

  1. 在界⾯上创建三个 QLabel

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

  3. 运⾏程序, 观察效果

代码⽰例: 显⽰图⽚

  1. 在界⾯上创建⼀个 QLabel, objectName 为 label
  2. 创建 resource.qrc ⽂件, 并把图⽚导⼊到 qrc 中.
  1. 修改 widget.cpp, 给 QLabel 设置图⽚

    执⾏程序, 观察效果

    这个图⽚并没有把 QLabel 填充满.

  2. 修改代码, 设置 scaledContents 属性

    再次运⾏, 观察效果, 可以看到图⽚已经被拉伸, 可以把窗⼝填满了.

  3. 此时, 如果拖动窗⼝⼤⼩, 可以看到图⽚并不会随着窗⼝⼤⼩的改变⽽同步变化

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

    执⾏程序, 此时改变窗⼝⼤⼩, 图⽚也会随之变化.

    于此同时, 在控制台⾥也能够看到尺⼨变化的过程.

代码⽰例: ⽂本对⻬, ⾃动换⾏, 缩进, 边距

  1. 创建四个 label

    并且在 QFrame 中设置 frameShape 为 Box (设置边框之后看起来会更清晰⼀些)

  2. 编写 widget.cpp, 给这四个 label 设置属性

  3. 运⾏程序, 可以看到如下效果

    第⼀个 label 垂直⽔平居中

    第⼆个 label 设置了 wordWrap, 能够⾃动换⾏

    第三个 label 设置了 Indent, 左侧和上⽅和边框有间距. 右侧则没有.

    第四个 label 设置了 margin, 四个⽅向均有间距

代码⽰例: 设置伙伴

  1. 创建两个 label 和 两个 radioButton.

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

    其中 & 后⾯跟着的字符, 就是快捷键.

    可以通过 alt + A 的⽅式来触发该快捷键.

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

  3. 运⾏程序, 可以看到, 按下快捷键 alt + a 或者 alt + b, 即可选中对应的选项

LCD Number

QLCDNumer 是⼀个专⻔⽤来显⽰数字的控件. 类似于 "⽼式计算器" 的效果.

属性 说明
intValue QLCDNumber 显⽰的数字值(int).
value QLCDNumber 显⽰的数字值(double).和 intValue 是联动的.设置 value 和 intValue 的⽅法名字为 display
digitCount 显⽰⼏位数字

代码⽰例: 倒计时

  1. 在界⾯上创建⼀个 QLCDNumber , 初始值设为 10.

  2. 修改 widget.h 代码, 创建⼀个 QTimer 成员, 和⼀个 updateTime 函数

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

    QTimer 表⽰定时器. 通过 start ⽅法启动定时器之后, 就会每隔⼀定周期, 触发⼀次QTimer::timeout 信号.

    使⽤ connect 把 QTimer::timeout 信号和 Widget::updateTime 连接起来, 意味着每次触发 QTimer::timeout 都会执⾏ Widget::updateTime

  4. 修改 widget.cpp, 实现 updateTime

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

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

  5. 执⾏程序, 可以看到每隔⼀秒钟, 显⽰的数字就减少 1

ProgressBar

使⽤ QProgressBar 表⽰⼀个进度条.

属性 说明
minimum 进度条最⼩值
maximum 进度条最⼤值
value 进度条当前值
alignment ⽂本在进度条中的对⻬⽅式
textVisible 进度条的数字是否可⻅

代码⽰例: 设置进度条按时间增⻓

  1. 在界⾯上创建进度条, objectName 为 progressBar

  2. 修改 widget.h, 创建 QTimer 和 updateProgressBar 函数

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

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

  4. 修改 widget.cpp, 实现 updateProgressBar

  5. 运⾏程序, 可以看到进度条中的进度在快速增⻓

Calendar Widget

QCalendarWidget 表⽰⼀个 "⽇历"

属性 说明
selectDate 当前选中的⽇期
minimumDate 最⼩⽇期
maximumDate 最⼤⽇期
firstDayOfWeek 每周的第⼀天(也就是⽇历的第⼀列)
gridVisible 是否显⽰表格的边框
selectionMode 是否允许选择⽇期
dateEditEnabled 是否允许⽇期被编辑

重要信号

信号 说明
selectionChanged(const QDate&) 当选中的⽇期发⽣改变时发出
activated(const QDate&) 当双击⼀个有效的⽇期或者按下回⻋键时发出,形参是⼀个QDate类型,保存了选中的⽇期
currentPageChanged(int,int) 当年份⽉份改变时发出,形参表⽰改变后的新年份和⽉份

代码⽰例: 获取选中的⽇期

  1. 在界⾯上创建⼀个 QCalendarWidget 和 ⼀个 label

  2. 给 QCalendarWidget 添加 slot 函数

  3. 执⾏程序, 可以看到当选择不同的⽇期时, label 中的内容就会随之改变.

输⼊类控件

Line Edit

QLineEdit ⽤来表⽰单⾏输⼊框. 可以输⼊⼀段⽂本, 但是不能换⾏.

属性 说明
text 输⼊框中的⽂本
inputMask 输⼊内容格式约束
maxLength 最⼤⻓度
frame 是否添加边框
echoMode 显⽰⽅式
cursorPosition 光标所在位置
alignment ⽂字对⻬⽅式, 设置⽔平和垂直⽅向的对⻬
dragEnabled 是否允许拖拽
readOnly 是否是只读的(不允许修改)

核⼼信号

属性 说明
void cursorPositionChanged(int old, int new) 当⿏标移动时发出此信号,old为先前的位置,new为新位置
void editingFinished() 当按返回或者回⻋键时,或者⾏编辑失去焦点时,发出此信号
void returnPressed() 当返回或回⻋键按下时发出此信号.如果设置了验证器, 必须要验证通过, 才能触发.
void selectionChanged() 当选中的⽂本改变时,发出此信号
void textChanged(const QString &text) 当QLineEdit中的⽂本改变时,发出此信号,text是新的⽂本。代码对⽂本的修改能够触发这个信号
void textEdited(const QString &text)) 当QLineEdit中的⽂本改变时,发出此信号,text是新的⽂本。代码对⽂本的修改不能触发这个信号

代码⽰例: 录⼊个⼈信息

  1. 在界⾯上创建三个输⼊框和两个单选按钮, ⼀个普通按钮

  2. 编写 widget.cpp, 在构造函数中编写初始化代码

  3. 继续修改 widget.cpp, 给按钮添加 slot 函数

  4. 执⾏程序, 可以看到, 随着⽤⼾输⼊内容之后, 点击按钮, 就能打印到输⼊的信息

代码⽰例: 使⽤正则表达式验证输⼊框的数据

此处要求在输⼊框中输⼊⼀个合法的电话号码(1 开头, 11 位, 全都是数字). 如果验证不通过, 则确定按钮⽆法点击

  1. 在界⾯上创建输⼊框和⼀个按钮.

  2. 编写 widget.cpp, 把按钮初始 enabled 设为 false. 给输⼊框添加验证器

    使⽤ QRegExp 创建⼀个正则表达式对象. "^1\d{10}$" 表⽰ "以 1 开头, 后⾯跟上任意的10个⼗进制数字"

    使⽤ QRegExpValidator 创建⼀个验证器对象. Qt 中内置了四个主要的验证器对象

  3. 编写 widget.cpp, 给 lineEdit 添加 textEdited 信号的 slot 函数

    on_lineEdit_textEdited 的参数是当前输⼊框的内容

    通过 lineEdit->validator() 获取到内置的验证器

    通过 validate ⽅法验证⽂本是否符合要求:第⼀个参数填写的是要验证的字符串. 由于参数要求是 QString& ⽽不是 const QString& , 需要把这个变量复制⼀下;第⼆个参数是⼀个 int&, 是输出型参数. 当验证的字符串不匹配时, 返回这个字符串的⻓度;返回值是⼀个枚举. QValidator::Acceptable 表⽰验证通过,QValidator::Invalid 表⽰验证不通过

  4. 执⾏程序, 观察效果. 可以看到此时尝试输⼊字⺟是⽆法输⼊的. 并且只有当输⼊的内容符合要求, 确定按钮才能被使⽤

代码⽰例: 验证两次输⼊的密码⼀致

  1. 在界⾯上创建两个输⼊框和⼀个 label

  2. 编写代码, 设置两个输⼊框的 echoMode 为 Password

  3. 给两个输⼊框设置 textEdited slot 函数

  4. 执⾏程序, 观察效果

    可以看到当两个输⼊框内的密码不相同时, 就会提⽰密码不相同

代码⽰例: 切换显⽰密码

  1. 创建⼀个输⼊框和⼀个复选按钮

  2. 修改 widget.cpp, 设置输⼊框的 echoMode 为 Password

  3. 修改 widget.cpp, 给 checkBox 添加 slot 函数

  4. 执⾏程序, 可以看到切换复选框的状态, 就可以控制输⼊框显⽰密码

Text Edit

QTextEdit 表⽰多⾏输⼊框. 也是⼀个富⽂本 & markdown 编辑器.

并且能在内容超出编辑框范围时⾃动提供滚动条

属性 说明
markdown 输⼊框内持有的内容. ⽀持 markdown 格式. 能够⾃动的对markdown ⽂本进⾏渲染成 html
html 输⼊框内持有的内容. 可以⽀持⼤部分 html 标签. 包括 img 和 table 等.
placeHolderText 输⼊框为空时提⽰的内容
readOnly 是否是只读的

核⼼信号

信号 说明
textChanged() ⽂本内容改变时触发
selectionChanged() 选中范围改变时触发
cursorPositionChanged() 光标移动时触发
undoAvailable(bool) 可以进⾏ undo 操作时触发
redoAvailable(bool) 可以进⾏ redo 操作时触发
copyAvaiable(bool) ⽂本被选中/取消选中时触发

代码⽰例: 获取多⾏输⼊框的内容

  1. 创建⼀个多⾏输⼊框和⼀个label

  2. 给多⾏输⼊框添加 slot 函数. 处理 textChanged 信号

    通过 toPlainText ⽅法获取到内部的⽂本.

  3. 执⾏程序, 可以看到当输⼊框中的内容发⽣变化时, label 中的内容同步发⽣改变

代码⽰例: 验证输⼊框的各种信号

  1. 创建多⾏输⼊框

  2. 给输⼊框添加以下⼏个 slot 函数

    QTextEdit 中包含了⼀个 QTextCursor 对象, 通过这个对象可以获取到当前光标位置和选中的内容.

  3. 执⾏程序, 观察结果

Combo Box

QComboBox 表⽰下拉框.

属性 说明
currentText 当前选中的⽂本
currentIndex 当前选中的条⽬下标从 0 开始计算. 如果当前没有条⽬被选中, 值为 -1
editable 是否允许修改;设为 true 时, QComboBox 的⾏为就⾮常接近 QLineEdit , 也可以设置 validator
iconSize 下拉框图标 (⼩三⻆) 的⼤⼩
maxCount 最多允许有多少个条⽬

核⼼⽅法

⽅法 说明
addItem(const QString&) 添加⼀个条⽬
currentIndex() 获取当前条⽬的下标;从 0 开始计算. 如果当前没有条⽬被选中, 值为-1
currentText() 获取当前条⽬的⽂本内容.

核⼼信号

⽅法 说明
activated(int);activated(const QString & text) 当⽤⼾选择了⼀个选项时发出.这个时候相当于⽤⼾点开下拉框, 并且⿏标划过某个选项.此时还没有确认做出选择.
currentIndexChanged(int);currentIndexChanged(const QString& text) 当前选项改变时发出.此时⽤⼾已经明确的选择了⼀个选项.⽤⼾操作或者通过程序操作都会触发这个信号
editTextChanged(const QString &text) 当编辑框中的⽂本改变时发出(editable 为 true 时有效)

代码⽰例: 使⽤下拉框模拟⻨当劳点餐

  1. 在界⾯上创建三个下拉框, 和⼀个按钮.

  2. 编写 widget.cpp, 初始化三个下拉框的内容

  3. 编写 widget.cpp, 给按钮添加 slot 函数

  4. 执⾏程序, 可以看到, 在点击确定按钮时, 就能获取到当前下拉框中选中的内容.

代码⽰例: 从⽂件中加载下拉框的选项

很多时候下拉框的选项并⾮是固定的, ⽽是通过读取⽂件/读取⽹络获取到的.

  1. 在界⾯上创建⼀个下拉框

  2. 创建⽂件 F:/config.txt , 编写选项. 每个选项占⼀⾏

  3. 修改 widget.cpp, 从⽂件中读取选项

    使⽤ ifstream 打开⽂件

    使⽤ getline 读取每⼀⾏

    使⽤ QString::fromStdString 把 std::string 转成 QString

  4. 执⾏程序, 可以看到⽂件内容已经被加载到下拉框中

Spin Box

使⽤ QSpinBox 或者 QDoubleSpinBox 表⽰ "微调框", 它是带有按钮的输⼊框. 可以⽤来输⼊整数/浮点数. 通过点击按钮来修改数值⼤⼩.

QSpinBox 关键属性

属性 说明
value 存储的数值
singleStep 每次调整的 "步⻓". 按下⼀次按钮数据变化多少
displayInteger 数字的进制. 例如 displayInteger 设为 10, 则是按照 10 进制表⽰. 设为 2 则为 2进制表⽰
minimum 最⼩值
maximum 最⼤值

核⼼信号

信号 说明
textChanged(QString) 微调框的⽂本发⽣改变时会触发.参数 QString 带有 前缀 和 后缀.
valueChanged(int) 微调框的⽂本发⽣改变时会触发.参数 int, 表⽰当前的数值.

代码⽰例: 调整⻨当劳购物⻋中的份数.

  1. 在界⾯上创建下列内容

  2. 编写代码, 修改 widget.cpp, 给下拉框设置初始值

  3. 编写代码, 给按钮添加 slot 函数

  4. 执⾏程序, 可以看到当⽤⼾选择不同的内容时, 点击按钮就能获取到对应的结果. 同时我们也⽆法输⼊⼀些超出范围的⾮法值

Date Edit & Time Edit

QDateTimeEdit 核⼼属性

属性 说明
dateTime 时间⽇期的值. 形如 2000/1/1 0:00:00
date 单纯⽇期的值. 形如 2001/1/1
time 单纯时间的值. 形如 0:00:00
displayFormat 时间⽇期格式. 形如 yyyy/M/d H:mm

核⼼信号

信号 说明
dateChanged(QDate) ⽇期改变时触发.
timeChanged(QTime) 时间改变时触发.
dateTimeChanged(QDateTime) 时间⽇期任意⼀个改变时触发.

代码⽰例: 实现⽇期计算器

  1. 在界⾯上创建两个 QDateTimeEdit 和⼀个按钮, ⼀个 label

  2. 编写计算按钮的 slot 函数

    使⽤ daysTo 函数可以计算两个⽇期的天数

    使⽤ secsTo 函数可以计算两个时间的秒数

    通过 (秒数 / 3600) 换算成⼩时数, 再余上 24 得到零⼏个⼩时

    使⽤ QString::number 把整数转成 QString 进⾏拼接

  3. 执⾏程序, 观察结果

Dial

使⽤ QDial 表⽰⼀个 旋钮.

核⼼属性

属性 说明
value 持有的数值.
minimum 最⼩值
maximum 最⼤值
singleStep 按下⽅向键的时候改变的步⻓.
pageStep 按下 pageUp / pageDown 的时候改变的步⻓.
sliderPosition 界⾯上旋钮显⽰的 初始位置

核⼼信号

属性 说明
valueChanged(int) 数值改变时触发
rangeChanged(int, int) 范围变化时触发

代码⽰例: 调整窗⼝透明度

  1. 在界⾯上创建⼀个旋钮和⼀个 label

  2. 编写 widget.cpp, 对旋钮初始化

  3. 编写 widget.cpp, 设置旋钮的 valueChanged slot 函数

  4. 运⾏程序, 观察效果. 可以看到随着拖动旋钮旋转, 不透明度发⽣明显变化

Slider

使⽤ QSlider 表⽰⼀个滑动条.

核⼼属性

属性 说明
value 持有的数值.
minimum 最⼩值
maximum 最⼤值
singleStep 按下⽅向键的时候改变的步⻓.
pageStep 按下 pageUp / pageDown 的时候改变的步⻓
sliderPosition 滑动条显⽰的 初始位置

核⼼信号

属性 说明
valueChanged(int) 数值改变时触发
rangeChanged(int, int) 范围变化时触发

代码⽰例: 调整窗⼝⼤⼩

  1. 在界⾯上创建两个滑动条, 分别是⽔平和垂直滑动条

  2. 编写代码初始化滑动条

  3. 编写滑动条的 valueChanged slot 函数

  4. 执⾏程序, 可以看到调整滑动条, 窗⼝⼤⼩就会随之改变

代码⽰例: 通过⾃定义快捷键调整滑动条位置

设置 - 减⼩ value, 设置 + 增加 value

  1. 在界⾯上创建滑动条和 label

  2. 编写初始化代码

  3. 创建 valueChanged 的 slot 函数

  4. 修改 widget.cpp 构造函数, 增加快捷键

    使⽤ QShortCut 类设置快捷键

    快捷键触发时, 会发出 QShortcut::activated 信号, 我们连接到⾃⼰写的 slot 函数

  5. 编写⾃定义 slot 函数

  6. 执⾏程序, 观察效果. 可以看到此时按下 - 和 + 就可以调整 value 的值

多元素控件

List Widget

使⽤ QListWidget 能够显⽰⼀个纵向的列表

属性 说明
currentRow 当前被选中的是第⼏⾏
count ⼀共有多少⾏
sortingEnabled 是否允许排序
isWrapping 是否允许换⾏
itemAlignment 元素的对⻬⽅式
selectRectVisible 被选中的元素矩形是否可⻅
spacing 元素之间的间隔

核⼼⽅法

方法 说明
addItem(const QString& label);addItem(QListWidgetItem *item) 列表中添加元素
currentItem() 返回 QListWidgetItem* 表⽰当前选中的元素
setCurrentItem(QListWidgetItem* item) 设置选中哪个元素
setCurrentRow(int row) 设置选中第⼏⾏的元素
insertItem(const QString& label, int row);insertItem(QListWidgetItem *item, int row) 在指定的位置插⼊元素
item(int row) 返回 QListWidgetItem* 表⽰第 row ⾏的元素
takeItem(int row) 删除指定⾏的元素, 返回 QListWidgetItem* 表⽰是哪个元素被删除

核⼼信号

方法 说明
currentItemChanged(QListWidgetItemcurrent, QListWidgetItem old) 选中不同元素时会触发. 参数是当前选中的元素和之前选中的元素
currentRowChanged(int) 选中不同元素时会触发. 参数是当前选中元素的⾏数
itemClicked(QListWidgetItem* item) 点击某个元素时触发
itemDoubleClicked(QListWidgetItem*item) 双击某个元素时触发
itemEntered(QListWidgetItem* item) ⿏标进⼊元素时触发

代码⽰例: 使⽤ ListWidget

  1. 在界⾯上创建⼀个 ListView , 右键 => 变形为 => ListWidget , 再创建⼀个 lineEdit 和 两个按钮.

  2. 编写 widget.cpp, 在构造函数中添加初始元素

  3. 编写 listWidget 的 slot 函数

    此处需要判定 current 和 previous ⾮空. 初始情况下是没有元素选中的, 就导致这俩指针可能是 NULL.

  4. 编写按钮的 slot 函数

  5. 执⾏程序, 观察效果. 可以新增元素, 选中元素, 删除元素

Table Widget

使⽤ QTableWidget 表⽰⼀个表格控件. ⼀个表格中包含若⼲⾏, 每⼀⾏⼜包含若⼲列.

表格中的每个单元格, 是⼀个 QTableWidgetItem 对象

QTableWidget核⼼⽅法

方法 说明
item(int row, int column) 根据⾏数列数获取指定的 QTableWidgetItem*
setItem(int row, int column,QTableWidget*) 根据⾏数列数设置表格中的元素
currentItem() 返回被选中的元素 QTableWidgetItem*
currentRow() 返回被选中元素是第⼏⾏
currentColumn() 返回被选中元素是第⼏列

QTableWidgetItem 核⼼信号

信号 说明
cellClicked(int row, int column) 点击单元格时触发
cellDoubleClicked(int row, int column) 双击单元格时触发
cellEntered(int row, int column) ⿏标进⼊单元格时触发
currentCellChanged(int row, int column, int previousRow, int previousColumn) 选中不同单元格时触发

QTableWidgetItem 核⼼⽅法

方法 说明
row() 获取当前是第⼏⾏
column() 获取当前是第⼏列
setText(const QString&) 设置⽂本
setTextAlignment(int) 设置⽂本对⻬
setIcon(const QIcon&) 设置图标
setSelected(bool) 设置被选中
setSizeHints(const QSize&) 设置尺⼨
setFont(const QFont&) 设置字体

代码⽰例: 使⽤ QTableWidget

  1. 在界⾯上创建 QTableWidget 和 三个按钮, ⼀个输⼊框

  2. 编写 widget.cpp 构造函数, 构造表格中的初始数据.

  3. 编写按钮的 slot 函数

  4. 执⾏程序, 即可完成表格的基本操作

Tree Widget

使⽤ QTreeWidget 表⽰⼀个树形控件. ⾥⾯的每个元素, 都是⼀个 QTreeWidgetItem , 每个QTreeWidgetItem 可以包含多个⽂本和图标, 每个⽂本/图标为⼀个 列.

可以给 QTreeWidget 设置顶层节点(顶层节点可以有多个), 然后再给顶层节点添加⼦节点, 从⽽构成树形结构.

QTreeWidget 核⼼⽅法

方法 说明
clear 清空所有⼦节点
addTopLevelItem(QTreeWidgetItem* item) 新增顶层节点
topLevelItem(int index) 获取指定下标的顶层节点
topLevelItemCount() 获取顶层节点个数
indexOfTopLevelItem(QTreeWidgetItem* item) 查询指定节点是顶层节点中的下标

QTreeWidget 核⼼信号

信号 说明
currentItemChanged(QTreeWidgetItemcurrent, QTreeWidgetItem old) 切换选中元素时触发
itemClicked(QTreeWidgetItem* item, int col) 点击元素时触发
itemDoubleClicked(QTreeWidgetItem* item,int col) 双击元素时触发
itemEntered(QTreeWidgetItem* item, int col) ⿏标进⼊时触发
itemExpanded(QTreeWidgetItem* item) 元素被展开时触发
itemCollapsend(QTreeWidgetItem* item) 元素被折叠时触发

QTreeWidgetItem 核⼼属性

属性 说明
text 持有的⽂本
textAlignment ⽂本对⻬⽅式
icon 持有的图表
font ⽂本字体
hidden 是否隐藏
disabled 是否禁⽤
expand 是否展开
sizeHint 尺⼨⼤⼩
selected 是否选中

QTreeWidgetItem 核⼼⽅法

方法 说明
addChild(QTreeWidgetItem* child) 新增⼦节点
childCount() ⼦节点的个数
child(int index) 获取指定下标的⼦节点. 返回 QTreeWidgetItem*
takeChild(int index) 删除对应下标的⼦节点
removeChild(QTreeWidgetItem*child) 删除对应的⼦节点
parent() 获取该元素的⽗节点

代码⽰例: 使⽤ QTreeWidget

  1. 在界⾯上创建⼀个 TreeView , 右键 => 变形为 => TreeWidget , 再创建⼀个 lineEdit 和 两个按钮.

  2. 编写代码, 构造初始数据

  3. 编写代码, 实现按钮的 slot 函数

  4. 执⾏程序, 可以针对树形框进⾏编辑

容器类控件

Group Box

使⽤ QGroupBox 实现⼀个带有标题的分组框. 可以把其他的控件放到⾥⾯作为⼀组.

核⼼属性

属性 说明
title 分组框的标题
alignment 分组框内部内容的对⻬⽅式
flat 是否是 "扁平" 模式
checkable 是否可选择
checked 描述分组框的选择状态 (前提是 checkable 为 true)

代码⽰例: 给⻨当劳案例加上分组框

  1. 在界⾯上创建三个分组框, 并且在分组框内部创建下拉框和微调框.

  2. 编写 widget.cpp, 添加初始化下拉框的代码

  3. 运⾏程序, 观察效果

Tab Widget

使⽤ QTabWidget 实现⼀个带有标签⻚的控件, 可以往⾥⾯添加⼀些 widget. 进⼀步的就可以通过标签⻚来切换.

核⼼属性

属性 说明
tabPosition 标签⻚所在的位置.
currentIndex 当前选中了第⼏个标签⻚ (从 0 开始计算)
currentTabText 当前选中的标签⻚的⽂本
currentTabName 当前选中的标签⻚的名字
currentTabIcon 当前选中的标签⻚的图标
currentTabToolTip 当前选中的标签⻚的提⽰信息
tabsCloseable 标签⻚是否可以关闭
movable 标签⻚是否可以移动

核⼼信号

信号 说明
currentChanged(int) 在标签⻚发⽣切换时触发, 参数为被点击的选项卡编号.
tabBarClicked(int) 在点击选项卡的标签条的时候触发. 参数为被点击的选项卡编号
tabBarDoubleClicked(int) 在双击选项卡的标签条的时候触发. 参数为被点击的选项卡编号.
tabCloseRequest(int) 在标签⻚关闭时触发. 参数为被关闭的选项卡编号

代码⽰例: 使⽤标签⻚管理多组控件

  1. 在界⾯上创建⼀个 QTabWidget , 和两个按钮.

  2. 编写 widget.cpp, 进⾏初始化, 给标签⻚中放个简单的 label

    注意新创建的 label 的⽗元素, 是 ui->tab 和 ui->tab_2

  3. 编写按钮的 slot 函数

    使⽤ count() 获取到标签⻚的个数.

    使⽤ addTab 新增标签⻚.

    使⽤ removeTab 删除标签⻚

    使⽤ currentIndex 获取到当前标签⻚的下标

    使⽤ setCurrentIndex 切换当前标签⻚.

  4. 编写 QTabWidget 的 currentChanged 函数

  5. 运⾏程序, 观察效果

    点击新建标签⻚, 可以创建出新的标签

    点击删除当前标签⻚, 可以删除标签

    切换标签⻚时, 可以看到 qDebug 打印出的标签⻚编号

布局管理器

之前使⽤ Qt 在界⾯上创建的控件, 都是通过 "绝对定位" 的⽅式来设定的.

也就是每个控件所在的位置, 都需要计算坐标, 最终通过 setGeometry 或者 move ⽅式摆放过去.

这种设定⽅式其实并不⽅便. 尤其是界⾯如果内容⽐较多, 不好计算. ⽽且⼀个窗⼝⼤⼩往往是可以调整的, 按照绝对定位的⽅式, 也⽆法⾃适应窗⼝⼤⼩.

因此 Qt 引⼊ "布局管理器" (Layout) 机制, 来解决上述问题

垂直布局

使⽤ QVBoxLayout 表⽰垂直的布局管理器. V 是 vertical 的缩写.

核⼼属性

属性 说明
layoutLeftMargin 左侧边距
layoutRightMargin 右侧边距
layoutTopMargin 上⽅边距
layoutBottomMargin 下⽅边距
layoutSpacing 相邻元素之间的间距

代码⽰例: 使⽤ QVBoxLayout 管理多个控件.

  1. 编写代码, 创建布局管理器和三个按钮. 并且把按钮添加到布局管理器中

    使⽤ addWidget 把控件添加到布局管理器中

    使⽤ setLayout 设置该布局管理器到 widget 中

  2. 运⾏程序, 可以看到此时界⾯上的按钮就存在于布局管理器中. 随着窗⼝尺⼨变化⽽发⽣改变

    通过上述代码的⽅式, 只能给这个 widget 设定⼀个布局管理器. 实际上也可以通过 Qt Design 在⼀个窗⼝中创建多个布局管理器

⽔平布局

使⽤ QHBoxLayout 表⽰垂直的布局管理器. H 是 horizontal 的缩写.

核⼼属性 (和 QVBoxLayout 属性是⼀致的)

代码⽰例: 使⽤ QHBoxLayout 管理控件

  1. 编写代码, 创建布局管理器和三个按钮. 并且把按钮添加到布局管理器中.

  2. 运⾏程序, 可以看到此时界⾯上的按钮就存在于布局管理器中. 随着窗⼝尺⼨变化⽽发⽣改变

⽹格布局

Qt 中还提供了 QGridLayout ⽤来实现⽹格布局的效果. 可以达到 M * N 的这种⽹格的效果.

核⼼属性

属性 说明
layoutLeftMargin 左侧边距
layoutRightMargin 右侧边距
layoutTopMargin 上⽅边距
layoutBottomMargin 下⽅边距
layoutHorizontalSpacing 相邻元素之间⽔平⽅向的间距
layoutVerticalSpacing 相邻元素之间垂直⽅向的间距
layoutRowStretch ⾏⽅向的拉伸系数
layoutColumnStretch 列⽅向的拉伸系数

代码⽰例: 使⽤ QGridLayout 管理元素

  1. 代码中创建 QGridLayout 和 4 个按钮

    使⽤ addWidget 添加控件到布局管理器中. 但是添加的同时会指定两个坐标. 表⽰放在第⼏⾏, 第⼏列.

  2. 执⾏代码, 观察效果. 可以看到当前的这⼏个按钮是按照 2 ⾏ 2 列的⽅式排列的

  3. 如果调整⾏列坐标为下列代码

    执⾏代码, 可以看到这⼏个按钮都在同⼀⾏了. 相当于 QHBoxLayout

代码⽰例: 设置 QGridLayout 中元素的⼤⼩⽐例

  1. 创建 6 个按钮, 按照 2 ⾏ 3 列的⽅式排列

    使⽤ setColumnStretch 设置每⼀列的拉伸系数

  2. 执⾏程序, 可以看到每⼀列的宽度是不同的. 并且随着窗⼝调整动态变化

表单布局

除了上述的布局管理器之外, Qt 还提供了 QFormLayout , 属于是 QGridLayout 的特殊情况, 专⻔⽤于实现两列表单的布局.

代码⽰例: 使⽤ QFormLayout 创建表单

  1. 编写代码, 创建 QFormLayout , 以及三个 label 和三个 lineEdit

    使⽤ addRow ⽅法来添加⼀⾏. 每⾏包含两个控件. 第⼀个控件固定是 QLabel / ⽂本, 第⼆个控件则可以是任意控件

    如果把第⼀个参数填写为 NULL, 则什么都不显⽰.

  2. 执⾏程序, 可以看到以下结果

Spacer

使⽤布局管理器的时候, 可能需要在控件之间, 添加⼀段空⽩. 就可以使⽤ QSpacerItem 来表⽰

核⼼属性

属性 说明
width 宽度
height ⾼度
hData ⽔平⽅向的 sizePolicy
vData 垂直⽅向的 sizePolicy

代码⽰例: 创建⼀组左右排列的按钮

  1. 在界⾯上创建⼀个 QVBoxLayout , 并添加两个按钮

  2. 直接运⾏程序, 可以看到两个按钮是紧挨着的

  3. 在两个按钮中间添加⼀个 spacer

  4. 运⾏程序, 观察代码效果. 可以看到两个按钮之间已经存在了间隔.

相关推荐
呆萌很16 分钟前
C++ 集合 list 使用
c++
Oneforlove_twoforjob25 分钟前
【Java基础面试题033】Java泛型的作用是什么?
java·开发语言
engchina41 分钟前
如何在 Python 中忽略烦人的警告?
开发语言·人工智能·python
向宇it42 分钟前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
诚丞成1 小时前
计算世界之安生:C++继承的文水和智慧(上)
开发语言·c++
Smile灬凉城6661 小时前
反序列化为啥可以利用加号绕过php正则匹配
开发语言·php
lsx2024061 小时前
SQL MID()
开发语言
Dream_Snowar2 小时前
速通Python 第四节——函数
开发语言·python·算法
西猫雷婶2 小时前
python学opencv|读取图像(十四)BGR图像和HSV图像通道拆分
开发语言·python·opencv
鸿蒙自习室2 小时前
鸿蒙UI开发——组件滤镜效果
开发语言·前端·javascript