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():点了取消 / 关了窗口
相关推荐
island13141 分钟前
CANN GE(图引擎)深度解析:计算图优化管线、内存静态规划与异构任务的 Stream 调度机制
开发语言·人工智能·深度学习·神经网络
坚持就完事了5 分钟前
Java中的集合
java·开发语言
魔芋红茶9 分钟前
Python 项目版本控制
开发语言·python
wjhx14 分钟前
QT中对蓝牙权限的申请,整理一下
java·数据库·qt
踏过山河,踏过海15 分钟前
【qt-查看对应的依赖的一种方法】
qt·visual studio
云小逸24 分钟前
【nmap源码解析】Nmap OS识别核心模块深度解析:osscan2.cc源码剖析(1)
开发语言·网络·学习·nmap
冰暮流星25 分钟前
javascript之二重循环练习
开发语言·javascript·数据库
风指引着方向26 分钟前
自定义算子开发入门:基于 CANN op-plugin 的扩展实践
开发语言
Fairy要carry31 分钟前
面试-GRPO强化学习
开发语言·人工智能
Liekkas Kono43 分钟前
RapidOCR Python 贡献指南
开发语言·python·rapidocr