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():点了取消 / 关了窗口
相关推荐
Wenweno0o1 天前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
chenjingming6661 天前
jmeter线程组设置以及串行和并行设置
java·开发语言·jmeter
cch89181 天前
Python主流框架全解析
开发语言·python
不爱吃炸鸡柳1 天前
C++ STL list 超详细解析:从接口使用到模拟实现
开发语言·c++·list
十五年专注C++开发1 天前
RTTR: 一款MIT 协议开源的 C++ 运行时反射库
开发语言·c++·反射
Momentary_SixthSense1 天前
设计模式之工厂模式
java·开发语言·设计模式
‎ദ്ദിᵔ.˛.ᵔ₎1 天前
STL 栈 队列
开发语言·c++
勿忘,瞬间1 天前
数据结构—顺序表
java·开发语言
张張4081 天前
(域格)环境搭建和编译
c语言·开发语言·python·ai
weixin_423533991 天前
【Windows11离线安装anaconda、python、vscode】
开发语言·vscode·python