Qt 窗口部件
Qt 窗口部件
[TOC]
1 基础窗口部件QWidget
QWidget类是所有用户界面对象的基类,即基础窗口部件。
QWidget 继承自
QObject和QPaintDevice。
QObject 提供 Qt 对象模型、信号槽、父子对象等机制;
QPaintDevice 表示该对象可以作为绘图设备,被 QPainter 绘制。
1.1 窗口与子部件
- 窗口是没有父部件的部件,即
顶级部件(top-level widget)。 - 非窗口部件称为
子部件(child widget)。
在构造函数里面,
- 如果传入
父部件 parent widget,通常成为该 parent 内部的子部件; - 如果没有 parent,通常成为顶级窗口。
例如:
1 | QLabel *label = new QLabel(this); |
这里this=parent,于是QLabel对象会变成this窗口里面的一个子控件。
1 | QLabel *label = new QLabel; |
这里QLabel对象没有父对象,于是它自己就是一个独立窗口。
1.2 窗口类型
窗口一般都有边框和标题栏。QWidget的构造函数有两个形参:
1 | QWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); |
参数 f 是 Qt::WindowFlags 类型,是 Qt::WindowType 枚举值的按位或组合。
注意是按位或,而不是逻辑或,举例(仅示例,非真实值):
1 | Qt::Dialog 0001 |
那么Qt::Dialog | Qt::FramelessWindowHint就变成0011,表示两个属性都打开。
1 | // ========================= |
1.3 窗口几何
1 | // ========================= |
2 对话框QDialog
2.1 模态和非模态对话框
模态对话框
modal dialog:没有关闭之前,不能与同一个应用程序的其他窗口进行交互。非模态对话框
modeless dialog:可以与它交互,也可以与同一程序中的其他窗口交互。
常见写法:
1 | //modal dialog |
exec() 会打开模态事件循环。
1 | //modeless dialog |
Q: modeless dialog必须new吗?
A: 不一定必须 new,但非模态对话框经常需要 new。
原因:
如果你写局部变量:
1
2
3
4
5 void MainWindow::openDialog()
{
QDialog dlg(this);
dlg.show();
}问题是:函数一结束,dlg 就被销毁了,所以窗口可能一闪而过。
所以非模态常写成:
1
2
3
4
5 void MainWindow::openDialog()
{
QDialog *dlg = new QDialog(this);
dlg->show();
}这样函数结束后,对话框还活着。
- 有一种特殊形式:
用setModal(true)建立 modal dialog。
例如:
1 | void MainWindow::onSaveClicked() { |
对比一下:
exec()
= 同步(阻塞)show() + setModal(true)
= 更接近异步
- 补充介绍:setWindowModality()
作用是设置“模态范围”:
1 | void QWidget::setWindowModality(Qt::WindowModality windowModality); |
常见枚举值:
1 | Qt::NonModal // 非模态 |
2.2 标准对话框
2.2.1 QMessageBox
这是消息对话框。
使用时加#include <QMessageBox>
例如:
提示
1 | QMessageBox::information(this, "提示", "保存成功"); |
警告
1 | QMessageBox::warning(this, "警告", "文件不存在"); |
错误
1 | QMessageBox::critical(this, "错误", "程序崩溃"); |
询问
1 | QMessageBox::question(this, "确认", "确定删除吗?"); |
2.2.2 QFileDialog
这是文件对话框。
使用时加#include <QFileDialog>
- 用于:
打开文件
保存文件
选择文件夹
打开文件
1 | QString fileName = QFileDialog::getOpenFileName(this, "选择文件", "", "Images (*.png *.jpg)"); |
保存文件
1 | QString fileName = QFileDialog::getSaveFileName(this, "保存文件"); |
选择目录
1 | QString dir = QFileDialog::getExistingDirectory(this, "选择目录"); |
2.2.3 QColorDialog
这是颜色对话框。
使用时加#include <QColorDialog>
1 | QColor color = QColorDialog::getColor(Qt::white, this); |
2.2.4 QFontDialog
这是字体对话框。
使用时加#include <QFontDialog>
用于:
选择字体
字号
粗体
1 | bool ok; |
2.2.5 QInputDialog
这是输入对话框。
使用时加#include <QInputDialog>
输入文本
1 | QString text = QInputDialog::getText(this, "输入", "请输入名字:"); |
输入整数
1 | int value = QInputDialog::getInt(this, "输入", "请输入数字:"); |
输入浮点数
1 | double value = QInputDialog::getDouble(this, "输入", "请输入数值:"); |
2.2.6 QProgressDialog
这是进度对话框。
使用时加#include <QProgressDialog>
用于:
下载进度
加载资源
长时间任务
1 | QProgressDialog dlg("正在下载...", "取消", 0, 100, this); |
3 QFrame类
QFrame类是带有边框的部件的基类。子类例如:QLabel,QAbstractScrollArea,等等。
Qt 中名称带有 Abstract 的类通常表示抽象基类,一般不直接实例化,主要用于提供公共接口。
最核心的两个概念
- FrameShape(边框形状)
1 | setFrameShape(...) |
常见值:
1 | QFrame::NoFrame // 无边框 |
- FrameShadow(阴影效果)
1 | setFrameShadow(...) |
常见值:
1 | QFrame::Plain // 平面 |
一个完整例子
1 | QFrame *frame = new QFrame(this); |
4 按钮部件
QAbstractButton是按钮部件的抽象基类。
4.1 QPushButton
这是普通按钮。
例如:
确定
取消
发送
关闭
创建按钮
1 | QPushButton *btn = new QPushButton("发送", this); |
常用函数
1 | void setText(const QString &text); // 设置按钮文本 |
最核心信号
1 | void clicked(bool checked = false); |
4.2 QToolButton
这是工具按钮。
常用于:
工具栏
悬浮按钮
图标按钮
- 特点:通常只有图标,没有大按钮边框
1 | QToolButton *btn = new QToolButton(this); |
4.3 QRadioButton
这是单选按钮。
例如:
○ 男
○ 女
○ 浅色模式
○ 深色模式
- 特点:同一父部件下的多个
QRadioButton通常互斥,只能选一个;如果需要自定义分组,可使用QButtonGroup。
1 | QRadioButton *radio = new QRadioButton("深色模式", this); |
常用函数
1 | void setChecked(bool checked); |
4.4 QCheckBox
这是复选按钮。
例如:
☑ 开机启动
☑ 启用动画
☑ 置顶显示
- 特点:可以同时选多个
1 | QCheckBox *check = new QCheckBox("开机启动", this); |
常用函数
1 | void setChecked(bool checked); |
4.5 补充
QGroupBox 可以理解成:“带标题的控件分组框”,把一组相关控件包起来。
最基本用法
1 | QGroupBox *group = new QGroupBox("系统设置", this); |
最重要的作用是逻辑分组,通常会配合布局。
例如:
1 | QVBoxLayout *layout = new QVBoxLayout; |
- 一个很重要的功能
可勾选 GroupBox
1 | group->setCheckable(true); |
1 | ☑ 启用高级设置 |
取消勾选时,整个组里的控件会自动禁用。
常用函数:
1 | // 设置分组框标题 |
5 QLineEdit
QLineEdit 是 Qt Widgets 中的单行文本输入控件。
5.1 创建
1 | QLineEdit *edit = new QLineEdit(this); |
带初始文本:
1 | QLineEdit *edit = new QLineEdit("hello", this); |
5.2 常用函数
5.2.1 设置文本
1 | void setText(const QString &text); |
5.2.2 获取文本
1 | QString text() const; |
5.2.3 清空文本
1 | void clear(); |
5.2.4 占位文本
1 | void setPlaceholderText(const QString &text); |
例如:
1 | edit->setPlaceholderText("请输入 API Key"); |
5.3 密码模式
1 | void setEchoMode(EchoMode mode); |
常用:
1 | QLineEdit::Normal //正常显示 |
例如:
1 | edit->setEchoMode(QLineEdit::Password); |
5.4 输入限制
5.4.1 最大长度
1 | void setMaxLength(int); |
5.4.2 只读
1 | void setReadOnly(bool); |
5.4.3 输入验证
1 | void setValidator(const QValidator *validator); |
常用:
1 | QIntValidator |
5.5 常用信号
5.5.1 文本变化
1 | void textChanged(const QString &text); |
5.5.2 编辑完成
1 | void editingFinished(); |
5.5.3 按下回车
1 | void returnPressed(); |
6 QAbstractSpinBox
QAbstractSpinBox 是 Qt 中“微调输入框”的抽象基类。
1 | QAbstractSpinBox |
它提供的是一类通用能力:文本输入框 + 上下调节按钮
6.1 QSpinBox
这是整数输入框。
1 | QSpinBox *spin = new QSpinBox(this); |
6.2 QDoubleSpinBox
这是浮点数输入框。
1 | QDoubleSpinBox *spin = new QDoubleSpinBox(this); |
6.3 QDateTimeEdit
这是日期时间输入框。
1 | QDateTimeEdit *edit = new QDateTimeEdit(this); |
6.4 QAbstractSpinBox 常用函数集合
6.4.1 QAbstractSpinBox 本身常用函数
1 | // 设置是否只读;只读后用户不能手动修改内容 |
6.4.2 按钮样式枚举
1 | // 显示上下箭头按钮 |
6.4.3 QSpinBox 常用函数
QSpinBox 用于整数输入。
1 | // 设置整数范围 |
6.4.4 QDoubleSpinBox 常用函数
QDoubleSpinBox 用于浮点数输入。
1 | // 设置浮点数范围 |
6.5 常用信号
1 | // QSpinBox 数值变化时触发 |
7 QAbstractSlider
QAbstractSlider 是 Qt 中“滑动调节类控件”的抽象基类。
1 | QAbstractSlider |
7.1 QSlider
普通滑块控件。
1 | QSlider *slider = new QSlider(Qt::Horizontal, this); |
常见效果:
1 | 0 ─────●──────── 100 |
7.2 QScrollBar
滚动条控件。
1 | QScrollBar *bar = new QScrollBar(Qt::Vertical, this); |
常见效果:
1 | ▲ |
7.3 QDial
旋钮控件。
1 | QDial *dial = new QDial(this); |
常见效果:
1 | ◜●◝ |
类似旋钮,常用于音量、角度、仪表盘调节。
7.4 QAbstractSlider 常用函数
1 | // 设置最小值 |
7.5 常用方向枚举
1 | // 水平方向 |
7.6 常用信号
1 | // 当前值变化时触发 |
7.7 简单示例
1 | QSlider *slider = new QSlider(Qt::Horizontal, this); |
1 | 范围:0 到 100 |
连接信号:
1 | connect(slider, &QSlider::valueChanged, this, &MainWindow::onValueChanged); |
