PyQt5关闭独立Python文件创建的窗口后触发函数报错如何解决?
问题修复方案
错误原因
你遇到的报错不是循环导入导致的,核心问题有两个:
do_something是主窗口Marker类的实例方法,必须绑定到具体的实例对象才能调用,你代码中直接传入类对象first_window.Marker作为self参数,类本身不会携带实例才有的label_1属性,所以触发AttributeError。- 让两个窗口模块互相导入的写法逻辑耦合度过高,确实存在循环导入的隐患,完全没有必要。
修复步骤
我们用Qt原生的信号槽机制实现需求,不需要第二个窗口感知主窗口的存在,既避免耦合也能解决问题。
1. 修改第二个窗口(second_dialog.py)
删除无用的导入和错误调用,仅保留自身关闭逻辑即可:
from PyQt5 import QtWidgets, QtCore from PyQt5.QtCore import Qt, pyqtSignal from PyQt5.QtGui import QPainter, QColor from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout from PyQt5.QtWidgets import QPushButton from sys import exit as sysExit class Marker(QWidget): # 可选:自定义关闭信号,需要传参数时用 close_signal = pyqtSignal() def __init__(self): QWidget.__init__(self) self.resize(350, 250) self.openbtn = QPushButton('close') self.openbtn.clicked.connect(self.Close) HBox = QHBoxLayout() HBox.addWidget(self.openbtn) HBox.addStretch(1) VBox = QVBoxLayout() VBox.addLayout(HBox) VBox.addStretch(1) self.setLayout(VBox) def Close(self): # 发射自定义关闭信号,需要传参时可以在emit里加参数 self.close_signal.emit() self.close() def paintEvent(self, event): p = QPainter(self) p.fillRect(self.rect(), QColor(128, 128, 128, 128)) if __name__ == "__main__": MainEventThred = QApplication([]) MainApp = Marker() MainApp.show() MainEventThred.exec()
2. 修改主窗口(first_window.py)
绑定第二个窗口的关闭信号到你要执行的do_something方法即可,两种可选实现:
方案A:直接绑定QWidget自带的destroyed信号
不需要修改第二个窗口的逻辑,直接用系统自带信号:
def open_dialog(self): self.box = second_dialog.Marker() # 绑定第二个窗口销毁信号到目标函数 self.box.destroyed.connect(self.do_something) self.box.show()
方案B:绑定自定义关闭信号
如果关闭时需要从第二个窗口回传参数,用自定义信号更灵活:
def open_dialog(self): self.box = second_dialog.Marker() # 绑定自定义关闭信号到目标函数 self.box.close_signal.connect(self.do_something) self.box.show()
修改后主窗口完整代码如下:
from PyQt5 import QtWidgets, QtCore from PyQt5.QtCore import Qt from PyQt5.QtGui import QPainter, QColor from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout from PyQt5.QtWidgets import QPushButton import second_dialog # the second window I am importing from sys import exit as sysExit class Marker(QWidget): def __init__(self): QWidget.__init__(self) self.resize(350, 250) self.openbtn = QPushButton('open') self.openbtn.clicked.connect(self.open_dialog) self.label_1 = QtWidgets.QLabel() self.label_1.setGeometry(QtCore.QRect(10, 20, 150, 31)) self.label_1.setObjectName("label_1") self.label_1.setText("HEy") HBox = QHBoxLayout() HBox.addWidget(self.openbtn) HBox.addWidget(self.label_1) HBox.addStretch(1) VBox = QVBoxLayout() VBox.addLayout(HBox) VBox.addStretch(1) self.setLayout(VBox) def open_dialog(self): self.box = second_dialog.Marker() # 二选一即可,不需要的注释掉 self.box.destroyed.connect(self.do_something) # self.box.close_signal.connect(self.do_something) self.box.show() def do_something(self): self.label_1.setText("Closed") def paintEvent(self, event): p = QPainter(self) p.fillRect(self.rect(), QColor(128, 128, 128, 128)) if __name__ == "__main__": MainEventThred = QApplication([]) MainApp = Marker() MainApp.show() MainEventThred.exec()
内容的提问来源于stack exchange,提问作者Mehul
相关产品推荐
相关产品推荐

