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():点了取消 / 关了窗口
相关推荐
疯狂的喵1 天前
C++编译期多态实现
开发语言·c++·算法
2301_765703141 天前
C++中的协程编程
开发语言·c++·算法
m0_748708051 天前
实时数据压缩库
开发语言·c++·算法
lly2024061 天前
jQuery Mobile 表格
开发语言
惊讶的猫1 天前
探究StringBuilder和StringBuffer的线程安全问题
java·开发语言
m0_748233171 天前
30秒掌握C++核心精髓
开发语言·c++
Fleshy数模1 天前
从数据获取到突破限制:Python爬虫进阶实战全攻略
java·开发语言
Duang007_1 天前
【LeetCodeHot100 超详细Agent启发版本】字母异位词分组 (Group Anagrams)
开发语言·javascript·人工智能·python
froginwe111 天前
Redis 管道技术
开发语言
u0109272711 天前
C++中的RAII技术深入
开发语言·c++·算法