关闭一个window(不是子window)后执行一个函数?
Execute a function after closing a window (not a child window)?
我的应用程序中有一个按钮,单击该按钮后会打开另一个 window(这是一个单独的 python 文件)。
我想在第二个 window 关闭后执行一个函数。有什么方法可以捕获 window 的 'closed' 信号或类似信号吗?
这是我的代码:(主要window)
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.dialog = QtWidgets.QWidget()
self.box = second_dialog.Marker()
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()
这是第二个的代码window:
from PyQt5 import QtWidgets
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 first_window
from sys import exit as sysExit
class Marker(QWidget):
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):
TEST_draggable.Marker.do_something(first_window.Marker)
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()
代码不 运行 并抛出此错误:
Traceback (most recent call last):
File "some/path/second_dialog.py", line 28, in Close
TEST_draggable.Marker.do_something(first_window.Marker)
File "some/path/first_window.py", line 39, in do_something
self.label_1.setText("clicked")
AttributeError: type object 'Marker' has no attribute 'label_1'
[1] 7552 abort (core dumped) /usr/local/bin/python3
我该如何解决这个问题?我查了很多论坛,怀疑循环进口是罪魁祸首,但我不确定。请帮忙。
这个问题与导入无关,而是因为您正在尝试 运行 实例 方法 class.
“罪魁祸首”来了:
TEST_draggable.Marker.do_something(first_window.Marker)
first_window.Marker
将用于 do_something
中的 self
参数,但由于它是 class,它没有 label_1
属性(仅class 的实例具有该属性)。我建议您研究一下 classes 和实例的一般工作方式,以及如何在 Python.
中处理它们
最简单的解决方案是为第二个 window 创建您自己的信号并将该信号连接到将“do_something”的函数上。然后,我们没有连接到新函数,而是从 closeEvent()
子 class 并从那里发送信号,这样即使用户单击标题栏上的专用按钮,我们也可以捕获关闭。请注意,如果您想更改 close
的行为,您只需 覆盖 它然后调用基本实现 (super().close()
) 而不是使用另一个函数名称 (顺便说一下,它不应该有大写的名称,因为它们应该只用于 classes 和常量)。
这是第二个class;请注意,对不同的 class 使用相同的名称是一个非常糟糕的主意。
from PyQt5.QtCore import pyqtSignal
class Marker(QWidget):
closed = pyqtSignal()
def __init__(self):
QWidget.__init__(self)
self.resize(350, 250)
self.openbtn = QPushButton('close')
self.openbtn.clicked.connect(<b>self.close</b>)
# ...
def closeEvent(self, event):
self.closed.emit()
然后,在第一个:
class Marker(QWidget):
# ...
def open_dialog(self):
self.dialog = QtWidgets.QWidget()
self.box = second_dialog.Marker()
self.box.closed.connect(self.do_something)
self.box.show()
我的应用程序中有一个按钮,单击该按钮后会打开另一个 window(这是一个单独的 python 文件)。
我想在第二个 window 关闭后执行一个函数。有什么方法可以捕获 window 的 'closed' 信号或类似信号吗?
这是我的代码:(主要window)
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.dialog = QtWidgets.QWidget()
self.box = second_dialog.Marker()
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()
这是第二个的代码window:
from PyQt5 import QtWidgets
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 first_window
from sys import exit as sysExit
class Marker(QWidget):
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):
TEST_draggable.Marker.do_something(first_window.Marker)
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()
代码不 运行 并抛出此错误:
Traceback (most recent call last):
File "some/path/second_dialog.py", line 28, in Close
TEST_draggable.Marker.do_something(first_window.Marker)
File "some/path/first_window.py", line 39, in do_something
self.label_1.setText("clicked")
AttributeError: type object 'Marker' has no attribute 'label_1'
[1] 7552 abort (core dumped) /usr/local/bin/python3
我该如何解决这个问题?我查了很多论坛,怀疑循环进口是罪魁祸首,但我不确定。请帮忙。
这个问题与导入无关,而是因为您正在尝试 运行 实例 方法 class.
“罪魁祸首”来了:
TEST_draggable.Marker.do_something(first_window.Marker)
first_window.Marker
将用于 do_something
中的 self
参数,但由于它是 class,它没有 label_1
属性(仅class 的实例具有该属性)。我建议您研究一下 classes 和实例的一般工作方式,以及如何在 Python.
最简单的解决方案是为第二个 window 创建您自己的信号并将该信号连接到将“do_something”的函数上。然后,我们没有连接到新函数,而是从 closeEvent()
子 class 并从那里发送信号,这样即使用户单击标题栏上的专用按钮,我们也可以捕获关闭。请注意,如果您想更改 close
的行为,您只需 覆盖 它然后调用基本实现 (super().close()
) 而不是使用另一个函数名称 (顺便说一下,它不应该有大写的名称,因为它们应该只用于 classes 和常量)。
这是第二个class;请注意,对不同的 class 使用相同的名称是一个非常糟糕的主意。
from PyQt5.QtCore import pyqtSignal
class Marker(QWidget):
closed = pyqtSignal()
def __init__(self):
QWidget.__init__(self)
self.resize(350, 250)
self.openbtn = QPushButton('close')
self.openbtn.clicked.connect(<b>self.close</b>)
# ...
def closeEvent(self, event):
self.closed.emit()
然后,在第一个:
class Marker(QWidget):
# ...
def open_dialog(self):
self.dialog = QtWidgets.QWidget()
self.box = second_dialog.Marker()
self.box.closed.connect(self.do_something)
self.box.show()