在 Qt 里,accept、reject、exec、open 主要都和 对话框(QDialog) 的生命周期与返回结果有关。下面按用途和区别讲清楚。
1️⃣ exec()
作用 :以模态方式 显示对话框,并阻塞当前代码执行
返回值 :QDialog::Accepted 或 QDialog::Rejected
cpp
QDialog dlg;
int result = dlg.exec();
if (result == QDialog::Accepted) {
// 点击了"确定"
}
特点
- 会进入一个本地事件循环
- 调用处会"停住",直到对话框关闭
- 适合:设置窗口、确认窗口、必须等用户操作的场景
exec() 示例(同步、阻塞)
场景:点击按钮,必须等用户点"确定 / 取消"后再继续执行代码。
cpp
void MainWindow::on_pushButton_clicked()
{
QDialog dlg(this);
if (dlg.exec() == QDialog::Accepted) {
qDebug() << "用户点了确定";
} else {
qDebug() << "用户点了取消";
}
qDebug() << "对话框已经关闭";
}
特点
exec()不返回,代码不会往下走- 对话框关闭后才继续执行
2️⃣ open()
作用 :以非阻塞模态 方式显示对话框
返回值:无(void)
cpp
dlg.open();
特点
- 不会阻塞当前代码
- 仍然是模态(不能操作父窗口)
- 结果通常通过 信号槽 获取
cpp
connect(&dlg, &QDialog::accepted, this, [](){
// 确定
});
connect(&dlg, &QDialog::rejected, this, [](){
// 取消
});
适合
- 不想卡住主流程
- Qt 推荐的新写法(尤其在异步/UI 复杂场景)
open() 示例(非阻塞、推荐)
场景:打开对话框,但主逻辑不想被卡住。
cpp
void MainWindow::on_pushButton_clicked()
{
QDialog *dlg = new QDialog(this);
connect(dlg, &QDialog::accepted, this, [](){
qDebug() << "用户点了确定";
});
connect(dlg, &QDialog::rejected, this, [](){
qDebug() << "用户点了取消";
});
dlg->open();
qDebug() << "open() 后立刻执行这里";
}
特点
- 不阻塞
- 结果用信号拿
- Qt 官方更推荐这种方式
3️⃣ accept()
作用 :关闭对话框,并设置结果为 Accepted
cpp
accept();
等价于:
cpp
done(QDialog::Accepted);
常见用途
- "确定 / OK" 按钮
- 表示用户确认操作成功
调用后:
exec()会返回Accepted- 会发出
accepted()信号
accept() 示例("确定"按钮)
场景:点"确定"关闭对话框并返回成功。
cpp
void MyDialog::on_okButton_clicked()
{
// 校验通过
accept();
}
等价于:
cpp
done(QDialog::Accepted);
效果
- 对话框关闭
exec()返回Accepted- 触发
accepted()信号
4️⃣ reject()
作用 :关闭对话框,并设置结果为 Rejected
cpp
reject();
等价于:
cpp
done(QDialog::Rejected);
常见用途
- "取消 / Cancel"
- 关闭窗口
- Esc 键
调用后:
exec()会返回Rejected- 会发出
rejected()信号
reject() 示例("取消 / 关闭"按钮)
场景:用户取消操作。
cpp
void MyDialog::on_cancelButton_clicked()
{
reject();
}
效果
- 对话框关闭
exec()返回Rejected- 触发
rejected()信号 - Esc 键默认也是走
reject()
5️⃣ 四者关系总结
| 方法 | 作用 | 是否关闭窗口 | 是否阻塞 | 结果 |
|---|---|---|---|---|
| exec() | 显示对话框 | 否 | ✅ 是 | 返回 Accepted / Rejected |
| open() | 显示对话框 | 否 | ❌ 否 | 用信号获取 |
| accept() | 确认并关闭 | ✅ 是 | --- | Accepted |
| reject() | 取消并关闭 | ✅ 是 | --- | Rejected |
6️⃣ 实际使用建议
- 简单同步逻辑 → 用
exec() - 推荐写法 / 异步 UI → 用
open() + 信号 - 按钮回调里 → 调
accept()/reject()
完整实战示例(最常见)
自定义对话框
cpp
class MyDialog : public QDialog
{
Q_OBJECT
public:
MyDialog(QWidget *parent = nullptr);
};
cpp
MyDialog::MyDialog(QWidget *parent)
: QDialog(parent)
{
QPushButton *ok = new QPushButton("确定");
QPushButton *cancel = new QPushButton("取消");
connect(ok, &QPushButton::clicked, this, &QDialog::accept);
connect(cancel, &QPushButton::clicked, this, &QDialog::reject);
}
调用方式 1(exec)
cpp
MyDialog dlg(this);
if (dlg.exec() == QDialog::Accepted) {
qDebug() << "确认操作";
}
调用方式 2(open)
cpp
MyDialog *dlg = new MyDialog(this);
connect(dlg, &QDialog::accepted, this, [](){
qDebug() << "确认操作";
});
dlg->open();
六、一句话记忆版
- exec():我要等你点完
- open():你慢慢点,我先干别的
- accept():点了确定
- reject():点了取消 / 关了窗口