Qt QMessageBox需关闭两次、调用show()立即消失的问题求解
问题原理说明
1. 弹窗需要关闭两次的原因
核心问题来自你代码中的两处错误:
- 第一,槽函数
on_actionAbout_triggered中,QMessageBox::exec()是阻塞式模态调用,会启动本地事件循环,直到你关闭弹窗才会返回,你在exec()返回后又调用了msgBox.show(),相当于第一次关闭模态弹窗后,立刻又弹出了同一个非模态弹窗,所以需要关闭第二次。你猜测的QApplication::exec()触发两次事件循环的假设不成立。 - 若删除多余的
show()调用后仍需要关闭两次,属于信号槽重复连接问题:Qt会自动将命名格式为on_<控件名>_<信号名>的槽和对应控件的信号绑定,你代码中又手动写了一次ui->actionAbout的triggered信号连接,导致同一个点击动作触发两次槽函数,弹出两次独立的弹窗。
2. 替换为show()后弹窗立刻消失的原因
你当前的QMessageBox是栈上分配的局部变量,show()是非阻塞调用,调用后会立刻返回继续执行后续代码,槽函数执行完毕后,栈上的msgBox变量会被自动析构销毁,弹窗也会跟着被回收,所以出现刚弹出就消失的情况。
解决方案
方案1:使用模态弹窗(关于弹窗推荐使用)
优先选择Qt自带的静态about方法,代码更简洁,也不会出现上述问题:
void TextEditor::on_actionAbout_triggered() { QMessageBox::about(this, "关于", QString("Project Name: %1\nVersion: %2") .arg(PROJECT_NAME) .arg(TextEditor_VERSION)); }
如果要手动构造QMessageBox,直接删除多余的show()调用即可:
void TextEditor::on_actionAbout_triggered() { const QString projectName = QString("Project Name: %1").arg(PROJECT_NAME); const QString version = QString("Version: %1").arg(TextEditor_VERSION); QMessageBox msgBox(this); msgBox.setText(projectName); msgBox.setInformativeText(version); msgBox.exec(); }
如果删除show()后仍有两次弹窗,删除手动写的重复信号槽连接即可:
// 从构造函数中删掉这行重复连接的代码 connect(ui->actionAbout, &QAction::triggered, this, &TextEditor::on_actionAbout_triggered);
方案2:使用非模态弹窗
需要在堆上创建QMessageBox,并设置关闭时自动销毁避免内存泄漏:
void TextEditor::on_actionAbout_triggered() { const QString projectName = QString("Project Name: %1").arg(PROJECT_NAME); const QString version = QString("Version: %1").arg(TextEditor_VERSION); QMessageBox *msgBox = new QMessageBox(this); msgBox->setAttribute(Qt::WA_DeleteOnClose); msgBox->setText(projectName); msgBox->setInformativeText(version); msgBox->show(); }
内容的提问来源于stack exchange,提问作者pennyBoy
相关产品推荐
相关产品推荐

