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

PyQt5主窗口检测其他窗口关闭事件未生效问题求助

问题分析
  • 核心逻辑问题:主窗口和子窗口各自实例化了独立的MySignal对象,两者没有关联,子窗口触发的是自己内部信号实例的信号,而主窗口绑定槽函数的是自身创建的另一个信号实例,自然收不到通知。
  • 代码细节问题:子窗口的closeEvent中调用了self.close()会触发递归调用closeEvent,导致程序异常;同时原有代码缺失QMainWindow、QWidget、QApplication的导入,无法直接运行。
修正代码(保留原中介信号类逻辑)
from PyQt5.QtWidgets import QPushButton, QMainWindow, QWidget, QApplication
from PyQt5.QtCore import QObject, pyqtSignal
import os, sys

class MySignal(QObject):
    signal = pyqtSignal()

class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 初始化主窗口
        self.setGeometry(100,100,300,200)
        self.setStyleSheet('background-color: blue')
        # 初始化控件
        self.widget = MyWidget()        
        self.btn = QPushButton(self)
        self.btn.setText('Click')
        self.btn.move(175, 150)
        self.btn.setStyleSheet('background-color: white')
        self.btn.clicked.connect(self.widget.showWidget)
        # 直接绑定子窗口的信号到主窗口槽函数
        self.widget.sig.signal.connect(self.changeToRed)
        self.show()
        
    def changeToRed(self):
        self.setStyleSheet('background-color: red')
        
    def closeEvent(self, event):
        os._exit(0)
        
class MyWidget(QWidget):
    def __init__(self):
        super().__init__() 
        self.setGeometry(500, 100, 200, 200)
        self.sig = MySignal()
        
    def showWidget(self):
        self.show()
        
    def closeEvent(self, event):
        self.sig.signal.emit()
        event.accept()
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyMainWindow()
    app.exec()
更简洁的实现方案

不需要单独创建中介信号类,直接在子Widget类中定义自定义信号即可,代码更易维护:

from PyQt5.QtWidgets import QPushButton, QMainWindow, QWidget, QApplication
from PyQt5.QtCore import pyqtSignal
import os, sys

class MyMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setGeometry(100,100,300,200)
        self.setStyleSheet('background-color: blue')
        self.widget = MyWidget()        
        self.btn = QPushButton(self)
        self.btn.setText('Click')
        self.btn.move(175, 150)
        self.btn.setStyleSheet('background-color: white')
        self.btn.clicked.connect(self.widget.show)
        self.widget.close_signal.connect(self.changeToRed)
        self.show()
        
    def changeToRed(self):
        self.setStyleSheet('background-color: red')
        
    def closeEvent(self, event):
        os._exit(0)
        
class MyWidget(QWidget):
    # 直接在类中定义自定义信号
    close_signal = pyqtSignal()
    def __init__(self):
        super().__init__() 
        self.setGeometry(500, 100, 200, 200)
        
    def closeEvent(self, event):
        self.close_signal.emit()
        event.accept()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyMainWindow()
    app.exec()

内容的提问来源于stack exchange,提问作者slalomchip

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:45:02