【QT】控件二(输入类控件、多元素控件、容器类控件与布局管理器)
文章目录
- 1.输入类控件
- 1.1 LineEdit
- 1.2 Text Edit
- 1.3 Combo Box
- 1.4 SpinBox
- 1.5 Date Edit & Time Edit
- 1.6 Dial
- 1.7 Slider
- 2. 多元素控件
- 2.1 List Widget
- 2.2 Table Widget
- 2.3 Tree Widget
- 3. 容器类控件
- 3.1 Group Box
- 3.2 Tab Widget
- 4. 布局管理器
- 4.1 垂直布局
- 4.2 水平布局
- 4.3 网格布局
- 4.4 表单布局
- 4.5 Spacer
1.输入类控件
1.1 LineEdit
QLineEdit ⽤来表示单行输⼊框,可以输⼊一段文本,但是不能换行
核心属性说明
属性 | 说明 |
---|---|
text | 输⼊框中的⽂本 |
inputMask | 输⼊内容格式约束 |
maxLength | 最⼤⻓度 |
frame | 是否添加边框 |
echoMode | 显⽰⽅式。QLineEdit::Normal :这是默认值,⽂本框会显⽰输⼊的⽂本。 QLineEdit::Password :在这种模式下,输⼊的字符会被隐藏,通常⽤星号(*)或等号(=)代替。 QLineEdit::NoEcho :在这种模式下,⽂本框不会显⽰任何输⼊的字符。 |
cursorPosition | 光标所在位置 |
alignment | 文字对齐方式,设置⽔平和垂直⽅向的对⻬ |
dragEnabled | 是否允许拖拽 |
readOnly | 是否是只读的(不允许修改);类似于label |
placeHolderText | 当输⼊框内容为空的时候,显示什么样的提⽰信息 |
clearButtonEnabled | 是否会自动显示出 “清除按钮” |
核心信号
信号 | 说明 |
---|---|
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是新的⽂本。 代码对⽂本的修改不能够触发这个信号 |
- 录入个人信息的案例:
- inputMask 只能进行简单的输⼊格式校验,实际开发中,基于正则表达式的方式是更核心的方法,下面我们来看一下正则表达式
此处要求在输⼊框中输⼊⼀个合法的电话号码(1 开头, 11 位, 全都是数字)。如果验证不通过,则确定按钮⽆法点击
- 使用
QRegExp
创建⼀个正则表达式对象. “^1\\d{10}$
” 表⽰ “以 1 开头, 后⾯跟上任意的10个⼗进制数字”. - 使用
QRegExpValidator
创建⼀个验证器对象. Qt 中内置了四个主要的验证器对象
给 lineEdit 添加 textEdited 信号的 slot 函数
执⾏程序,观察效果,可以看到此时尝试输⼊字⺟是⽆法输⼊的,并且只有当输⼊的内容符合要求,确定按钮才能被使⽤。
- 其它属性:Alignment、MaxLength、槽函数
- 切换显示密码
1.2 Text Edit
QTextEdit 表示多行输⼊框,也是⼀个富文本 & markdown 编辑器,并且能在内容超出编辑框范围时⾃动提供滚动条。
属性 | 说明 |
---|---|
markdown | 输⼊框内持有的内容. ⽀持 markdown 格式. 能够⾃动的对markdown ⽂本进⾏渲染成 html |
html | 输⼊框内持有的内容. 可以⽀持⼤部分 html 标签. 包括 img 和 table 等 |
placeHolderText | 输⼊框为空时提⽰的内容 |
readOnly | 是否是只读的 |
undoRedoEnable | 是否开启 undo / redo 功能。 按下 ctrl + z 触发 undo;按下 ctrl + y 触发 redo |
autoFormating | 开启⾃动格式化. |
tabstopWidth | 按下缩进占多少空间 |
overwriteMode | 是否开启覆盖写模式 |
acceptRichText | 是否接收富⽂本内容 |
verticalScrollBarPolicy | 垂直⽅向滚动条的出现策略 Qt::ScrollBarAsNeeded : 根据内容⾃动决定是否需要滚动条,这是默认值。 Qt::ScrollBarAlwaysOff : 总是关闭滚动条; Qt::ScrollBarAlwaysOn : 总是显⽰滚动条 |
horizontalScrollBarPolicy | ⽔平⽅向滚动条的出现策略 Qt::ScrollBarAsNeeded : 根据内容⾃动决定是否需要滚动条,这是默认值。 Qt::ScrollBarAlwaysOff : 总是关闭滚动条。 Qt::ScrollBarAlwaysOn : 总是显⽰滚动条。 |
核心信号:
信号 | 说明 |
---|---|
textChanged() | ⽂本内容改变时触发 |
selectionChanged() | 选中范围改变时触发 |
cursorPositionChanged() | 光标移动时触发 |
undoAvailable(bool) | 可以进⾏ undo 操作时触发 |
redoAvailable(bool) | 可以进⾏ redo 操作时触发 |
copyAvaiable(bool) | ⽂本被选中/取消选中时触发 |
- 获取多行输入框的内容
- 测试undo、redo、copy
1.3 Combo Box
QCombo Box 表示下拉框
属性 | 说明 |
---|---|
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 时有效) |
- 下面我们使用下拉框,实现一个点餐案例
很多时候下拉框的选项并非是固定的,而是通过读取文件/读取网络获取到的
- 从文件中读取
创建文件,编写选项,每个选项占⼀行
- Qt 中也提供了 QFile 实现读写⽂件的功能. 当然使⽤ C++ 标准库的 std::fstream 也是完全可以的.
- 之所以存在两套, 是因为 Qt 诞⽣较早 (1991 年左右), 此时 C++ 还没有完成 “标准化” 的⼯作, C++ 标准库这样的概念⾃然也没有诞⽣.
- 因此 Qt 就⾃⼰打造了⼀套库, 实现了字符串, 容器, ⽂件操作, 多线程, ⽹络操作, 定时器, 正则表达式等内容
1.4 SpinBox
使用 QSpinBox 或者 QDoubleSpinBox 表示 “微调框”,它是带有按钮的输⼊框, 可以⽤来输⼊整数/浮点数,通过点击按钮来修改数值大小
属性 | 说明 |
---|---|
value | 存储的数值 |
singleStep | 每次调整的 “步⻓”. 按下⼀次按钮数据变化多少 |
displayInteger | 数字的进制. 例如 displayInteger 设为 10, 则是按照 10 进制表⽰. 设为 2 则为 2 进制表⽰ |
minimum、maximum | 最小值、最大值 |
wrapping | 是否允许换行 |
suffix、prefix | 后缀、前缀 |
buttonSymbol | 按钮上的图标。UpDownArrows 上下箭头形式 PlusMinus 加减号形式 NoButtons 没有按钮 |
accelerated | 按下按钮时是否为快速调整模式 |
correctionMode | 输⼊有误时如何修正。如果⽤⼾输⼊了⼀个⽆效的值,那么SpinBox会恢复为上⼀个有效值 |
核心信号
信号 | 说明 |
---|---|
textChanged(QString) | 微调框的⽂本发⽣改变时会触发,参数 QString 带有 前缀 和 后缀 |
valueChanged(int) | 微调框的⽂本发⽣改变时会触发,参数 int 表⽰当前的数值 |
该控件较为简单,就不过多赘述了
1.5 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::ss (这⾥的格式化符号的含义,不同语⾔/库的设定规则是存在差异的) |
minimumDateTime、maximumDateTime | 最小、最大时间日期 |
timeSpec | Qt::LocalTime :显⽰本地时间、 Qt::UTC :显⽰协调世界时(UTC)、Qt::OffsetFromUTC :显⽰相对于UTC的偏移量(时差) |
核心信号
信号 | 说明 |
---|---|
dateChanged(QDate) | ⽇期改变时触发 |
timeChanged(QTime) | 时间改变时触发 |
dateTimeChanged(QDateTime) | 时间⽇期任意⼀个改变时触发. |
- 案例:实现日期计算器
- 使⽤ daysTo 函数可以计算两个⽇期的天数. time.daysTo(time2),使用time2-time1
- 使⽤ secsTo 函数可以计算两个时间的秒数.
- 通过 (秒数 / 3600) 换算成⼩时数, 再余上 24 得到零⼏个⼩时
1.6 Dial
使用 QDial 表示⼀个 旋钮
核心属性
属性 | 说明 |
---|---|
value | 持有的数值 |
minimum、maximum | 最小值、最大值 |
singleStep | 按下⽅向键的时候改变的步⻓ |
pageStep | 按下 pageUp / pageDown 的时候改变的步⻓ |
sliderPosition | 界面上旋钮显⽰的 初始位置 |
wrapping | 是否允许循环调整. 即数值如果超过最⼤值, 是否允许回到最⼩值. (调整过程能否 “套圈”) |
value | 持有的数值 |
notchesVisible | 是否显示刻度线 |
notchTarget | 刻度线之间的相对位置. 数字越⼤, 刻度线越稀疏. |
核心信号
信号 | 说明 |
---|---|
valueChanged(int) | 数值改变时触发 |
rangeChanged(int, int) | 范围变化时触发 |
使用旋钮调整不透明度
1.7 Slider
使用 QSlider 表示⼀个滑动条
QSlider
和 QDial 都是继承⾃QAbstractSlider
,因此⽤法上基本相同.
下面值罗列一下Slider的核心属性
属性 | 说明 |
---|---|
sliderPosition | 滑动条显⽰的 初始位置 |
tracking | 外观是否会跟踪数值变化. 默认值为 true. ⼀般不需要修改 |
orientation | 滑动条的⽅向是⽔平还是垂直 |
invertedAppearance | 是否要翻转滑动条的⽅向 |
tickPosition | 刻度的位置 |
tickInterval | 刻度的密集程度 |
- 案例: 在界面上创建两个滑动条,分别是水平和垂直滑动条,用来调整窗口大小
- 通过自定义快捷键调整滑动条位置
设置 - 减小 value,设置 = 增加 value
默认情况下滑动条可以通过方向键或者 pageUp / pageDown 调整大小
2. 多元素控件
Qt 中提供的多元素控件有:
- QListWidget
- QListView
- QTableWidget
- QTableView
- QTreeWidget
- QTreeView
QTableView
是基于 MVC 设计的控件,QTableView 自身不持有数据,使用 QTableView 的时候需要⽤⼾创建⼀个 Model 对象 (比如 QStandardModel ),并且把 Model 和 QTableView 关联起来,后续修改 Model 中的数据就会影响 QTableView 的显示;修改 QTableView 的显示也会影响到 Model 中的数据(双向绑定).QTableWidget
则是 QTableView 的子类,对 Model 进行了封装,不需要用户手动创建 Model 对象,直接就可以往 QTableWidget 中添加数据了
2.1 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* 表⽰是哪个元素被删除了 |
还有核心信号这里就不罗列了
在上述介绍中,涉及到⼀个关键的类, QListWidgetItem
,这个类表⽰ QListWidget 中的⼀个元素.
核心方法如下,本质上就是⼀个 “文本+图标” 构成的
方法 | 说明 |
---|---|
setFont | 设置字体 |
setIcon | 设置图标 |
setHidden | 设置隐藏 |
setSizeHint | 设置尺⼨ |
setSelected | 设置是否选中 |
setText | 设置⽂本 |
setTextAlignment | 设置⽂本对⻬⽅式 |
在界⾯上创建⼀个 ListView , 右键 => 变形为 => ListWidget
2.2 Table Widget
核心方法
- 创建表,设置表头名称
- 增加行/列
默认情况下,单元格中的内容直接就是可编辑的如果不想让用户编辑,可以设置 ui->tableWidget-> setEditTriggers(QAbstractItemView::NoEditTriggers);
2.3 Tree Widget
QTreeWidget 核心方法
QTreeWidgetItem 核心方法
方法 | 说明 |
---|---|
addChild(QTreeWidgetItem* child) | 新增⼦节点 |
childCount() | ⼦节点的个数 |
child(int index) | 获取指定下标的⼦节点. 返回 QTreeWidgetItem* |
takeChild(int index) | 删除对应下标的⼦节点 |
removeChild(QTreeWidgetItem* child) | 删除对应的⼦节点 |
parent() | 获取该元素的⽗节点 |
QTreeWidget 支持多列显示,每一列都有一个从左到右的索引编号。索引从 0 开始,0 表示第一列,1 表示第二列,依此类推
设置槽函数
3. 容器类控件
3.1 Group Box
使用 QGroupBox
实现⼀个带有标题的分组框,可以把其他的控件放到里面作为⼀组,这样看起来能更好看⼀点.
可以把控件放到Group Box中,这些内部的控件的父元素就是这个Group Box了
核心属性
方法 | 说明 |
---|---|
title | 分组框的标题 |
alignment | 分组框内部内容的对⻬⽅式 |
checkable | 是否可选择. 设为 true, 则在 title 前⽅会多出⼀个可勾选的部分 |
checked | 描述分组框的选择状态 (前提是 checkable 为 true) |
3.2 Tab Widget
使用 QTabWidget
实现⼀个带有标签页控件,可以往⾥⾯添加⼀些 widget. 进⼀步的就可以通过标签页来切换
核心属性
方法 | 说明 |
---|---|
tabPosition | 标签⻚所在的位置. North 上⽅ South 下⽅ West 左侧 East 右侧 |
currentIndex | 当前选中了第⼏个标签⻚ (从 0 开始计算) |
currentTabText | 当前选中的标签⻚的⽂本 |
currentTabName | 当前选中的标签⻚的名字 |
currentTabIcon | 当前选中的标签⻚的图标 |
currentTabToolTip | 当前选中的标签⻚的提⽰信息 |
tabsCloseable | 标签⻚是否可以关闭 |
movable | 标签⻚是否可以移动 |
核心信号
方法 | 说明 |
---|---|
currentChanged(int) | 在标签⻚发⽣切换时触发, 参数为被点击的选项卡编号 |
tabBarClicked(int) | 在点击选项卡的标签条的时候触发. 参数为被点击的选项卡编号. |
tabCloseRequest(int) | 在标签⻚关闭时触发,参数为被关闭的选项卡编号 |
实现部分槽函数
4. 布局管理器
之前使用 Qt 在界⾯上创建的控件,都是通过 “绝对定位” 的方式来设定的。也就是每个控件所在的位置,都需要计算坐标,最终通过 setGeometry 或者 move 方式摆放过去。
这种设定⽅式其实并不⽅便,尤其是界⾯如果内容⽐较多,不好计算。而且⼀个窗口大小往往是可以调整的, 按照绝对定位的⽅式,也⽆法自适应窗口大小。
因此 Qt 引⼊ “布局管理器” (Layout) 机制来解决上述问题
4.1 垂直布局
使用 QVBoxLayout
表示垂直的布局管理器( V 是 vertical 的缩写)
核心属性
方法 | 说明 |
---|---|
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上⽅边距 |
layoutBottomMargin | 下⽅边距 |
layoutSpacing | 相邻元素之间的间距 |
注意:Layout 只是⽤于界⾯布局,并没有提供信号
注意:⼀个 widget 只能包含⼀个 layout
通过 Qt Designer 创建的布局管理器,其实是先创建了⼀个 widget,设置过 geometry 属性的,再把这个 layout 设置到这个 widget 中,此时的布局并不会随着窗口大小的改变而改变
4.2 水平布局
核心属性与垂直布局相同,这里就不赘述了
使用嵌套布局
4.3 网格布局
Qt 中还提供了 QGridLayout
用来实现网格布局的效果,可以达到 M * N 的这种网格的效果
核心属性
方法 | 说明 |
---|---|
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上⽅边距 |
layoutBottomMargin | 下⽅边距 |
layoutHorizontalSpacing | 相邻元素之间⽔平⽅向的间距 |
layoutVerticalSpacing | 相邻元素之间垂直⽅向的间距 |
layoutRowStretch | ⾏⽅向的拉伸系数 |
layoutColumnStretch | 列⽅向的拉伸系数 |
设置行和列的时候,如果设置的是⼀个很⼤的值,但是这个值和上⼀个值之间并没有其他的元素,那么并不会在中间腾出额外的空间
另外,QGridLayout 也提供了 setRowStretch 设置⾏之间的拉伸系数,上述案例中,直接设置
setRowStretch
效果不明显,因为每个按钮的⾼度是固定的,需要把按钮的垂直⽅向的 sizePolicy 属性设置为
QSizePolicy::Expanding
尽可能填充满布局管理器,才能看到效果.
使用 setSizePolicy 设置按钮的尺⼨策略,可选的值如下:
QSizePolicy::Ignored
: 忽略控件的尺⼨,不对布局产⽣影响。QSizePolicy::Minimum
: 控件的最⼩尺⼨为固定值,布局时不会超过该值。QSizePolicy::Maximum
: 控件的最⼤尺⼨为固定值,布局时不会⼩于该值。QSizePolicy::Preferred
: 控件的理想尺⼨为固定值,布局时会尽量接近该值。QSizePolicy::Expanding
: 控件的尺⼨可以根据空间调整,尽可能占据更多空间。QSizePolicy::Shrinking
: 控件的尺⼨可以根据空间调整,尽可能缩⼩以适应空间
4.4 表单布局
上述的布局管理器之外,Qt 还提供了 QFormLayout,属于是 QGridLayout 的特殊情况,专门用于实现两列表单的布局。
这种表单布局多用于让用户填写信息的场景,左侧列为提示,右侧列为输⼊框
4.5 Spacer
使⽤布局管理器的时候, 可能需要在控件之间, 添加⼀段空⽩. 就可以使⽤ QSpacerItem 来表⽰.
方法 | 说明 |
---|---|
width | 宽度 |
height | ⾼度 |
hData | ⽔平⽅向的 sizePolicy |
vData | 垂直⽅向的 sizePolicy |