QT 对话框(QDialog)中 accept、reject、exec、open的使用

在 Qt 里,accept、reject、exec、open 主要都和 对话框(QDialog) 的生命周期与返回结果有关。下面按用途和区别讲清楚。


1️⃣ exec()

作用 :以模态方式 显示对话框,并阻塞当前代码执行
返回值QDialog::AcceptedQDialog::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():点了取消 / 关了窗口
相关推荐
微学AI5 小时前
一根针指向所有方向:挂谷猜想对 LLM Agent 技能-记忆架构的启示
开发语言·人工智能·架构·挂谷猜想
豆瓣鸡5 小时前
算法日记 - Day3
java·开发语言·算法
韭菜炒鸡肝天6 小时前
VTK开发笔记(一):VTK介绍,Qt..+VSx+VTK.编译
开发语言·笔记·qt
Aaron - Wistron7 小时前
Web API C# (Furion版)带 单元测试
开发语言·后端·c#
刀法孜然7 小时前
QT5.12.8开发中使用触摸屏,配置的环境变量,imx6ullpro开发板qt开发
qt
Dxy12393102168 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
0566468 小时前
Python康复训练——常用标准库
开发语言·python·学习
骊城英雄8 小时前
基于C#+avalonia ui实现的跨平台点胶机灌胶监控控制上位机软件
开发语言·ui·c#
吾儿良辰8 小时前
一个被BCL遗忘的高性能集合:C# CircularBuffer<T>深度解析
开发语言·windows·c#
昆曲之源_娄江河畔8 小时前
Python如何安装flask, pymssql
开发语言·python·flask·pymssql