PyQt5中重写窗口关闭按钮事件以恢复父窗口启用状态
解决PyQt5中窗口关闭后恢复父窗口启用状态的问题
你遇到的这个问题很常见——窗口B的系统关闭按钮(红色X)不会触发你手动绑定在Quit按钮上的启用窗口A的逻辑,所以我们需要给窗口B的关闭流程添加上对应的状态恢复操作。下面提供两种可靠的解决方案:
方法一:重写窗口的closeEvent方法
这是最直观的处理方式,我们可以在WindowTwo类中重写Qt内置的closeEvent函数,在窗口关闭前触发启用窗口A的逻辑,或者通过自定义信号让Controller统一处理(更符合解耦的设计原则)。
修改后的WindowTwo类代码:
class WindowTwo(QtWidgets.QWidget): switch_window = QtCore.pyqtSignal() # 添加自定义信号,通知外部窗口即将关闭 window_closing = QtCore.pyqtSignal() def __init__(self, M, S): QtWidgets.QWidget.__init__(self) self.S = S self.M = M self.setupUi(self) self.setWindowTitle('M') def setupUi(self, CM): # 原UI代码保持不变,此处省略 CM.setEnabled(True) CM.setFocusPolicy(QtCore.Qt.TabFocus) layout = QtWidgets.QGridLayout() layout.addWidget(QtWidgets.QLabel("M: " ),0,0) layout.addWidget(QtWidgets.QLabel("S: " ),0,1) self.QuitButton = QtWidgets.QPushButton("Quit") self.QContinueButton = QtWidgets.QPushButton("Continue") self.QuitButton.clicked.connect(CM.close) self.QContinueButton.clicked.connect(lambda: self.windowtwo(self.M)) layout.addWidget(self.QuitButton, 10, 1 ) layout.addWidget(self.QContinueButton, 10, 2 ) self.setLayout(layout) def windowtwo(self, M): self.M = M self.switch_window.emit() # 重写关闭事件 def closeEvent(self, event): # 发送关闭信号,让Controller处理窗口A的启用逻辑 self.window_closing.emit() # 允许窗口正常关闭 event.accept()
然后在Controller的show_window_four方法中绑定该信号:
def show_window_four(self, a): if (a == 100): self.window_four = WindowTwo(self.M, self.S) self.window_four.switch_window.connect(self.show_window_three) self.mscrollArea.setDisabled(1) # 绑定自定义关闭信号到启用窗口A的操作 self.window_four.window_closing.connect(lambda: self.mscrollArea.setDisabled(0)) # 修正原代码的小问题:close需要加括号才会执行 self.window_four.QuitButton.clicked.connect(lambda: self.window_four.close()) self.window_four.QuitButton.clicked.connect(lambda: self.mscrollArea.setDisabled(0)) self.window_four.show()
方法二:监听窗口的destroyed信号
如果你不想重写closeEvent,可以直接利用Qt窗口的destroyed信号——当窗口被销毁时自动触发启用窗口A的操作:
修改Controller的show_window_four方法:
def show_window_four(self, a): if (a == 100): self.window_four = WindowTwo(self.M, self.S) self.window_four.switch_window.connect(self.show_window_three) self.mscrollArea.setDisabled(1) # 监听窗口销毁信号,自动启用窗口A self.window_four.destroyed.connect(lambda: self.mscrollArea.setDisabled(0)) # 修正原代码的小问题:close需要加括号才会执行 self.window_four.QuitButton.clicked.connect(lambda: self.window_four.close()) self.window_four.QuitButton.clicked.connect(lambda: self.mscrollArea.setDisabled(0)) self.window_four.show()
额外优化提示
- 原代码中
self.window_four.QuitButton.clicked.connect(lambda: self.window_four.close)缺少括号,这会导致点击Quit按钮时不会触发窗口关闭,必须改为self.window_four.close()才能正常执行。 - 用信号的方式处理窗口间的状态同步,能让代码更模块化——窗口类只负责自身的UI和事件触发,Controller统一协调窗口逻辑,后续维护会更便捷。
内容的提问来源于stack exchange,提问作者AuroraS
相关产品推荐
相关产品推荐

