通用对话框:QMessageBox、QWizard
QMessageBox
QMessageBox
是 Qt 框架中用于显示标准对话框(提示信息、警告、错误、询问等)的类,属于 Qt Widgets 模块。它是一个简单但强大的 UI 元素,常用于向用户展示信息或要求用户做出选择。
基本用法
QMessageBox
的常用静态方法包括:
1
2
3
4
| QMessageBox::information(parent, title, message);
QMessageBox::warning(parent, title, message);
QMessageBox::critical(parent, title, message);
QMessageBox::question(parent, title, message);
|
示例:
1
2
3
4
| QMessageBox::information(this, "提示", "操作成功!");
QMessageBox::warning(this, "警告", "操作可能导致数据丢失!");
QMessageBox::critical(this, "错误", "无法连接服务器!");
QMessageBox::question(this, "确认", "确定要退出吗?");
|
获取用户选择
QMessageBox::question
可以用于获取用户是否确认操作:
1
2
3
4
5
6
| QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "退出", "确定要退出吗?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
QApplication::quit();
}
|
自定义按钮和图标
可以使用 QMessageBox
类构造函数来自定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| QMessageBox msgBox;
msgBox.setWindowTitle("自定义对话框");
msgBox.setText("是否保存更改?");
msgBox.setIcon(QMessageBox::Question);
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Yes:
// 处理保存
break;
case QMessageBox::No:
// 不保存
break;
case QMessageBox::Cancel:
// 取消操作
break;
}
|
QMessageBox 的常用方法
方法 | 功能 |
---|
setText() | 设置主信息文本 |
setInformativeText() | 设置附加信息(副标题) |
setDetailedText() | 设置详细信息(点击展开) |
setIcon() | 设置图标:Information、Warning、Critical、Question、NoIcon |
setStandardButtons() | 设置标准按钮(Yes, No, Cancel, Ok 等) |
setDefaultButton() | 设置默认按钮 |
exec() | 模态运行对话框,等待用户响应 |
show() | 非模态显示(不常用于 QMessageBox) |
图标枚举
图标枚举值 | 说明 | UI 表现 |
---|
QMessageBox::NoIcon | 无图标 | 无特殊图标 |
QMessageBox::Information | 信息提示 | 蓝色圆形带 “i” 的图标 |
QMessageBox::Warning | 警告 | 黄色三角形带感叹号 |
QMessageBox::Critical | 错误 | 红色圆圈带叉号 |
QMessageBox::Question | 询问 | 蓝色问号 |
按钮枚举
按钮枚举值 | 按钮文本(默认) | 用途 |
---|
QMessageBox::Ok | 确定(OK) | 一般确认操作 |
QMessageBox::Cancel | 取消(Cancel) | 取消当前操作 |
QMessageBox::Yes | 是(Yes) | 表示确认 |
QMessageBox::No | 否(No) | 表示拒绝 |
QMessageBox::Abort | 放弃(Abort) | 表示放弃操作(较少使用) |
QMessageBox::Retry | 重试(Retry) | 表示重试操作 |
QMessageBox::Ignore | 忽略(Ignore) | 表示忽略错误 |
QMessageBox::Close | 关闭(Close) | 关闭窗口或对话框 |
QMessageBox::Help | 帮助(Help) | 提供帮助信息 |
QMessageBox::Apply | 应用(Apply) | 应用更改但不关闭窗口 |
QMessageBox::Reset | 重置(Reset) | 恢复默认设置 |
QMessageBox::YesAll | 全部是(Yes to All) | 批量确认 |
QMessageBox::NoAll | 全部否(No to All) | 批量拒绝 |
QMessageBox::Save | 保存(Save) | 保存文件或数据 |
QMessageBox::Discard | 放弃(Discard) | 放弃未保存的更改 |
多个按钮可以使用 |
运算符组合,例如:
1
| QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel
|
高级用法(示例)
1
2
3
4
5
6
7
8
9
| QMessageBox box;
box.setWindowTitle("文件冲突");
box.setText("文件已存在");
box.setInformativeText("是否覆盖已有文件?");
box.setDetailedText("文件路径:/home/user/file.txt");
box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
box.setDefaultButton(QMessageBox::No);
box.setIcon(QMessageBox::Warning);
int ret = box.exec();
|
QWizard
QWizard
是 Qt 提供的一个 向导式对话框组件,适合用来引导用户完成多步操作,例如安装程序、配置引导等。它内部是多个页面(QWizardPage
)的集合,按步骤导航,自动处理“下一步”“上一步”“完成”等按钮逻辑。
基本结构
一个 QWizard
由多个 QWizardPage
组成:
1
2
3
4
5
6
| QWizard wizard;
wizard.addPage(new IntroPage());
wizard.addPage(new SettingsPage());
wizard.addPage(new ConclusionPage());
wizard.setWindowTitle("向导示例");
wizard.exec();
|
QWizardPage 简单继承
1
2
3
4
5
6
7
8
9
10
| class IntroPage : public QWizardPage {
public:
IntroPage(QWidget *parent = nullptr) : QWizardPage(parent) {
setTitle("欢迎");
QLabel *label = new QLabel("欢迎使用设置向导!");
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label);
setLayout(layout);
}
};
|
QWizard 常用方法
方法 | 说明 |
---|
addPage(QWizardPage*) | 添加页面 |
setPage(int id, QWizardPage*) | 设置指定 ID 页 |
setStartId(int id) | 设置起始页面 ID |
setWindowTitle(QString) | 设置窗口标题 |
exec() / show() | 运行向导 |
next() / back() | 手动跳转下一页/上一页 |
currentId() / currentPage() | 当前页信息 |
button(QWizard::Button) | 获取某个按钮(比如 Finish、Next) |
QWizardPage 常用方法
方法 | 说明 |
---|
setTitle(QString) | 设置页面标题 |
setSubTitle(QString) | 设置副标题 |
isComplete() | 页面是否已完成(会影响“下一步”按钮) |
registerField() | 注册字段,用于数据传递 |
initializePage() | 页面初始化时调用 |
validatePage() | 点击“下一步”时触发,返回 false 可阻止切换 |
页面间传值:registerField()
页面字段可以共享,便于数据流动:
1
2
| QLineEdit *nameLineEdit = new QLineEdit;
registerField("name*", nameLineEdit); // * 表示该字段必须填写
|
在别的页面中访问:
1
| QString name = field("name").toString();
|
枚举值 | 描述 |
---|
QWizard::BackButton | 返回按钮 |
QWizard::NextButton | 下一步按钮 |
QWizard::FinishButton | 完成按钮 |
QWizard::CancelButton | 取消按钮 |
QWizard::HelpButton | 帮助按钮 |
QWizard::CustomButton1~3 | 自定义按钮 |
获取或设置按钮文本:
1
| wizard.setButtonText(QWizard::FinishButton, "完成");
|
向导样式(QWizard::WizardStyle
枚举)
样式枚举 | 描述 |
---|
QWizard::ClassicStyle | 经典风格 |
QWizard::ModernStyle | 现代风格(默认) |
QWizard::MacStyle | macOS 风格 |
QWizard::AeroStyle | Windows Vista 风格(需支持) |
1
| wizard.setWizardStyle(QWizard::ModernStyle);
|
页面跳转控制
可以通过重载 QWizardPage::nextId()
决定下一页逻辑跳转:
1
2
3
4
5
6
| int IntroPage::nextId() const override {
if (someCondition)
return Page_Advanced;
else
return Page_Simple;
}
|
示例小程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| class IntroPage : public QWizardPage {
public:
IntroPage() {
setTitle("欢迎");
setSubTitle("本向导将引导你完成设置过程");
QLabel *label = new QLabel("请输入你的姓名:");
QLineEdit *lineEdit = new QLineEdit;
registerField("username*", lineEdit);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label);
layout->addWidget(lineEdit);
setLayout(layout);
}
};
class FinalPage : public QWizardPage {
public:
FinalPage() {
setTitle("完成");
QLabel *label = new QLabel("设置完成,点击完成退出。");
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label);
setLayout(layout);
}
void initializePage() override {
QString name = field("username").toString();
qDebug() << "用户输入的名字是:" << name;
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWizard wizard;
wizard.setWindowTitle("设置向导");
wizard.addPage(new IntroPage);
wizard.addPage(new FinalPage);
wizard.setWizardStyle(QWizard::ModernStyle);
return wizard.exec();
}
|
示例:引导页
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="btnMessageBox">
<property name="text">
<string>显示 QMessageBox</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnWizard">
<property name="text">
<string>启动 QWizard</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| #ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void showMessageBox();
void showWizard();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
| #include "widget.h"
#include "finalpage.h" // 自定义 QWizardPage 子类:完成页
#include "ui_widget.h"
#include "userinfopage.h" // 自定义 QWizardPage 子类:用户信息页
#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QWizard>
#include <QWizardPage>
Widget::Widget(QWidget* parent) : QWidget(parent), ui(new Ui::Widget) {
ui->setupUi(this); // 加载 UI 文件中的控件和布局
// 绑定按钮点击信号到对应槽函数
connect(ui->btnMessageBox, &QPushButton::clicked, this, &Widget::showMessageBox);
connect(ui->btnWizard, &QPushButton::clicked, this, &Widget::showWizard);
}
Widget::~Widget() {
delete ui; // 释放 UI 指针,防止内存泄漏
}
// 演示 QMessageBox 的用法
void Widget::showMessageBox() {
QMessageBox msgBox;
msgBox.setWindowTitle("QMessageBox 示例"); // 设置对话框标题
msgBox.setText("是否确认继续操作?"); // 主文本
msgBox.setInformativeText("此操作不可撤销!"); // 补充信息文本
msgBox.setIcon(QMessageBox::Warning); // 设置警告图标
// 设置标准按钮:Yes 和 No
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::No); // 默认选中 No 按钮
int ret = msgBox.exec(); // 以模态方式显示消息框,阻塞直到用户选择
// 根据用户选择显示不同的信息提示
if (ret == QMessageBox::Yes) {
QMessageBox::information(this, "结果", "你选择了是");
} else {
QMessageBox::information(this, "结果", "你选择了否");
}
}
// 演示 QWizard 的用法
void Widget::showWizard() {
QWizard wizard;
wizard.setWindowTitle("QWizard 示例"); // 设置向导窗口标题
wizard.setWizardStyle(QWizard::ModernStyle); // 设置向导风格(现代)
// 添加页面:必须是 QWizardPage 的子类实例
wizard.addPage(new UserInfoPage); // 用户信息输入页
wizard.addPage(new FinalPage); // 完成提示页
wizard.exec(); // 以模态方式启动向导,用户完成或取消时返回
}
|
userinfopage.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| #ifndef USERINFO_PAGE_H
#define USERINFO_PAGE_H
#include <QLineEdit>
#include <QWizardPage>
// UserInfoPage 继承自 QWizardPage,表示向导中的“用户信息”页面
class UserInfoPage : public QWizardPage {
Q_OBJECT
public:
// 构造函数,允许传入父窗口指针,默认 nullptr
explicit UserInfoPage(QWidget* parent = nullptr);
private:
QLineEdit* nameEdit; // 用于输入用户名的文本编辑控件
};
#endif // USERINFO_PAGE_H
|
userinfopage.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| #include "userinfopage.h"
#include <QLabel>
#include <QVBoxLayout>
UserInfoPage::UserInfoPage(QWidget *parent) : QWizardPage(parent) {
setTitle("用户信息"); // 设置该向导页的标题,显示在向导窗口顶部
QLabel *label = new QLabel("请输入你的名字:"); // 提示用户输入的文本标签
nameEdit = new QLineEdit; // 创建文本编辑框供用户输入名字
// 注册字段,允许通过 QWizard 的 field() 方法访问输入内容
// 字段名为 "username*",'*' 表示该字段是必填项,向导会强制要求用户填写
registerField("username*", nameEdit);
// 创建垂直布局,将标签和文本框垂直排列
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(label);
layout->addWidget(nameEdit);
// 设置页面布局,使控件显示在窗口中
setLayout(layout);
}
|
finalpage.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| #ifndef FINAL_PAGE_H
#define FINAL_PAGE_H
#include <QLabel>
#include <QWizardPage>
// FinalPage 继承自 QWizardPage,表示向导中的“完成”页面
class FinalPage : public QWizardPage {
Q_OBJECT
public:
// 构造函数,允许传入父窗口指针,默认 nullptr
explicit FinalPage(QWidget* parent = nullptr);
// 重写 QWizardPage 的 initializePage() 方法
// 每次页面显示时会调用,用于初始化页面内容
void initializePage() override;
private:
QLabel* infoLabel; // 用于显示欢迎信息的标签控件
};
#endif // FINAL_PAGE_H
|
finalpage.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| #include "finalpage.h"
#include <QVBoxLayout>
FinalPage::FinalPage(QWidget* parent) : QWizardPage(parent) {
setTitle("完成"); // 设置该向导页的标题,显示在向导窗口顶部
infoLabel = new QLabel; // 创建一个 QLabel 用于显示欢迎信息
QVBoxLayout* layout = new QVBoxLayout; // 垂直布局管理器,用于安排控件位置
layout->addWidget(infoLabel); // 将 QLabel 添加到布局中
setLayout(layout); // 将布局设置给该页面,使其生效
}
// 重写 QWizardPage 的 initializePage(),每次该页面显示时调用
void FinalPage::initializePage() {
// 从向导的字段中获取用户输入的用户名,字段名为 "username"
QString name = field("username").toString();
// 根据用户名动态设置标签文本,显示欢迎信息
infoLabel->setText("你好," + name + ",欢迎使用 QWizard!");
}
|