You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:01:34