PySide2点击按钮触发QMessageBox后关闭弹窗导致应用无报错退出问题
问题根因
代码的窗口结构不符合Qt的设计规范,是触发异常退出的核心原因:
MainWindow本身继承自QMainWindow,调用QUiLoader.load('main.ui', self)时相当于把UI文件中定义的窗口作为了MainWindow实例的子控件- 你没有展示外层的
MainWindow实例,只调用了mainWindow.ui.show()展示内层子窗口 - Qt的默认规则是所有可见顶级窗口关闭后自动退出应用,你创建
QMessageBox时指定的父对象是处于隐藏状态的外层MainWindow,关闭弹窗后Qt会误判没有存活的可见顶级窗口,因此直接退出应用。
解决方案
两种修改方式二选一即可:
方案1:调整窗口结构(推荐)
把加载的UI设置为MainWindow的中心部件,符合QMainWindow的设计规范:
class MainWindow(QtWidgets.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.set_and_load_ui() def set_and_load_ui(self): # 加载UI时不指定父对象 ui = QUiLoader().load('main.ui') # 将UI设置为当前主窗口的中心部件 self.setCentralWidget(ui) self.ui = ui # 剩下的trigger_messagebox、messagebox方法保持不变 def trigger_messagebox(self): self.messagebox() def messagebox(self,x=""): msg = QMessageBox(self) msg.setIcon(QMessageBox.Information) msg.setText("{}".format(x)) msg.setInformativeText("test") msg.setWindowTitle("test") msg.exec_() app = QtWidgets.QApplication(sys.argv) mainWindow = MainWindow() # 直接展示外层主窗口,不要只展示ui mainWindow.show() mainWindow.ui.mainmenuButton.clicked.connect(lambda: mainWindow.trigger_messagebox()) exit_code = app.exec_()
方案2:直接使用加载的UI作为主窗口
不需要额外套MainWindow层级,减少不必要的嵌套:
import sys from PyQt5 import QtWidgets from PyQt5.uic import QUiLoader from PyQt5.QtWidgets import QMessageBox app = QtWidgets.QApplication(sys.argv) # 直接加载UI作为主窗口 main_ui = QUiLoader().load('main.ui') def messagebox(x=""): msg = QMessageBox(main_ui) msg.setIcon(QMessageBox.Information) msg.setText("{}".format(x)) msg.setInformativeText("test") msg.setWindowTitle("test") msg.exec_() main_ui.mainmenuButton.clicked.connect(lambda: messagebox()) main_ui.show() exit_code = app.exec_()
修改完成后点击按钮触发弹窗,关闭弹窗后应用不会再异常退出。
内容的提问来源于stack exchange,提问作者greendino
相关产品推荐
相关产品推荐

