Qt Creator 5.0.2 C++双窗口并行运行子窗口打开即闪退问题求解
问题原因分析
- 局部变量生命周期问题:
Graphics gr是槽函数内的栈局部变量,on_pushButton_2_clicked函数执行完毕后,gr会被自动析构回收,调用show()属于异步方法,不会阻塞函数执行,所以会出现窗口刚打开就被销毁的闪退问题。 - 方法逻辑冲突问题:
QDialog::exec()是模态对话框专属的启动方法,即便设置了Qt::NonModal属性,exec()本身会启动独立的局部事件循环,阻塞主窗口的事件响应,直到第二个窗口关闭才会返回,因此无法实现两个窗口同时可用。
解决方案
方案1:复用单个子窗口实例(适合只需要打开一个子窗口的场景)
- 先在MainWindow的头文件中声明Graphics类指针作为成员变量,延长对象生命周期:
// mainwindow.h 文件新增内容 #include "graphics.h" class MainWindow : public QMainWindow { Q_OBJECT // 原有类代码无需修改,仅新增私有成员变量 private: Graphics *gr = nullptr; };
- 修改按钮点击槽函数的实现逻辑:
void MainWindow::on_pushButton_2_clicked() { // 首次点击时创建窗口实例,后续点击直接唤起已有窗口 if (!gr) { gr = new Graphics(this); // 传入this作为父对象,主窗口销毁时自动回收子窗口内存 gr->setWindowModality(Qt::NonModal); } gr->show(); gr->activateWindow(); // 可选配置,唤起窗口时自动置顶 }
方案2:每次点击生成独立子窗口(适合可打开多个子窗口的场景)
无需修改头文件,直接修改槽函数即可,窗口关闭时自动销毁释放内存:
void MainWindow::on_pushButton_2_clicked() { Graphics *gr = new Graphics; gr->setAttribute(Qt::WA_DeleteOnClose); // 窗口关闭时自动释放内存,避免泄漏 gr->setWindowModality(Qt::NonModal); gr->show(); }
注意事项
- 非模态窗口禁止使用
exec()方法启动,该方法仅适用于需要阻塞父窗口的模态对话框场景。 - 所有需要长期显示的UI对象不能定义为局部栈变量,必须用堆内存创建或存储为类成员变量,避免被提前析构。
内容的提问来源于stack exchange,提问作者Ruprecht
相关产品推荐
相关产品推荐

