如何删除对已关闭 windows 的所有引用?
How do I remove every reference to a closed windows?
在下面的示例中,我从主文件打开新的 child windows。对于每个新的 window,我在列表中添加了对它的引用以跟踪所有新的 window(我的整个软件中有很多)。
我的问题是当我打开了几个 windows 并关闭了其中一些时,对那些关闭的 windows 的引用仍然出现在列表中:
1 window open
[<__main__.window object at 0x000002B91B7D1798>]
2 windows open
[<__main__.window object at 0x000002B91B7D1798>, <__main__.window object at 0x000002B91B7D19D8>]
3 windows open
[<__main__.window object at 0x000002B91B7D1798>, <__main__.window object at 0x000002B91B7D19D8>, <__main__.window object at 0x000002B91B7D1C18>]
4 windows open
[<__main__.window object at 0x000002B91B7D1798>, <__main__.window object at 0x000002B91B7D19D8>, <__main__.window object at 0x000002B91B7D1C18>, <__main__.window object at 0x000002B91B7D1E58>]
hereI closed the first two windows, so 3 windows are opened, but I still have :
[<__main__.window object at 0x000002B91B7D1798>, <__main__.window object at 0x000002B91B7D19D8>, <__main__.window object at 0x000002B91B7D1C18>, <__main__.window object at 0x000002B91B7D1E58>, <__main__.window object at 0x000002B91B8640D8>]
我怎样才能真正关闭 child window 并且在我的列表中没有他们的参考?否则明显没有关闭。
这是 MRE
from PyQt5.QtWidgets import *
import sys
class window(QMainWindow):
def __init__(self, parent=None ):
super(window, self).__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.HBOX = QVBoxLayout()
self.PB = QPushButton('open new window')
self.PB.clicked.connect(self.new_window)
self.HBOX.addWidget(self.PB)
self.centralWidget.setLayout(self.HBOX)
self.windows_list = []
def new_window(self):
self.windows_list.append(window(self))
self.windows_list[-1].show()
print(self.windows_list)
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = window()
ex.show()
sys.exit(app.exec_())
请记住,关闭 window 不会 删除它(除非设置了 Qt.WA_DeleteOnClose
属性,默认情况下未设置)。
一个可能的解决方案是覆盖 closeEvent
并发送自定义信号。
class Window(QMainWindow):
closed = QtCore.pyqtSignal(object)
# ...
def new_window(self):
new_window = Window(self)
self.windows_list.append(new_window)
new_window.show()
new_window.closed.connect(self.window_list.remove)
def closeEvent(self, event):
self.closed.emit(self)
另一种可能性是始终设置 Qt.WA_DeleteOnClose
属性并连接到 destroyed
信号,但在这种情况下,您 不能 依赖信号参数(它与实际删除的 window 不匹配),并且必须使用带有 window 实例的 lambda 代替:
class Window(QMainWindow):
# ...
def new_window(self):
new_window = Window(self)
self.windows_list.append(new_window)
new_window.setAttribute(Qt.WA_DeleteOnClose)
new_window.show()
new_window.destroyed.connect(lambda: self.windows_list.remove(new_window))
请注意,我将 class 名称大写,因为 classes 不应使用小写名称。
您可以使用 closeEvent
:
发送信号
import sys
from PyQt5.QtCore import pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import (
QMainWindow, QApplication, QPushButton, QVBoxLayout, QWidget
)
from PyQt5.QtGui import QCloseEvent
class window(QMainWindow):
closed = pyqtSignal(QMainWindow)
def __init__(self, parent=None):
super(window, self).__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.HBOX = QVBoxLayout()
self.PB = QPushButton('open new window')
self.PB.clicked.connect(self.new_window)
self.HBOX.addWidget(self.PB)
self.centralWidget.setLayout(self.HBOX)
self.windows_list = []
def new_window(self):
new_window = window(self)
new_window.closed.connect(self.remove_window_from_list)
self.windows_list.append(new_window)
self.windows_list[-1].show()
print(self.windows_list)
@pyqtSlot(QMainWindow)
def remove_window_from_list(self, window: QMainWindow) -> None:
self.windows_list.remove(window)
print(self.windows_list)
@pyqtSlot(QCloseEvent)
def closeEvent(self, a0: QCloseEvent) -> None:
self.closed.emit(self)
super().closeEvent(a0)
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = window()
ex.show()
sys.exit(app.exec_())
在下面的示例中,我从主文件打开新的 child windows。对于每个新的 window,我在列表中添加了对它的引用以跟踪所有新的 window(我的整个软件中有很多)。 我的问题是当我打开了几个 windows 并关闭了其中一些时,对那些关闭的 windows 的引用仍然出现在列表中:
1 window open
[<__main__.window object at 0x000002B91B7D1798>]
2 windows open
[<__main__.window object at 0x000002B91B7D1798>, <__main__.window object at 0x000002B91B7D19D8>]
3 windows open
[<__main__.window object at 0x000002B91B7D1798>, <__main__.window object at 0x000002B91B7D19D8>, <__main__.window object at 0x000002B91B7D1C18>]
4 windows open
[<__main__.window object at 0x000002B91B7D1798>, <__main__.window object at 0x000002B91B7D19D8>, <__main__.window object at 0x000002B91B7D1C18>, <__main__.window object at 0x000002B91B7D1E58>]
hereI closed the first two windows, so 3 windows are opened, but I still have :
[<__main__.window object at 0x000002B91B7D1798>, <__main__.window object at 0x000002B91B7D19D8>, <__main__.window object at 0x000002B91B7D1C18>, <__main__.window object at 0x000002B91B7D1E58>, <__main__.window object at 0x000002B91B8640D8>]
我怎样才能真正关闭 child window 并且在我的列表中没有他们的参考?否则明显没有关闭。
这是 MRE
from PyQt5.QtWidgets import *
import sys
class window(QMainWindow):
def __init__(self, parent=None ):
super(window, self).__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.HBOX = QVBoxLayout()
self.PB = QPushButton('open new window')
self.PB.clicked.connect(self.new_window)
self.HBOX.addWidget(self.PB)
self.centralWidget.setLayout(self.HBOX)
self.windows_list = []
def new_window(self):
self.windows_list.append(window(self))
self.windows_list[-1].show()
print(self.windows_list)
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = window()
ex.show()
sys.exit(app.exec_())
请记住,关闭 window 不会 删除它(除非设置了 Qt.WA_DeleteOnClose
属性,默认情况下未设置)。
一个可能的解决方案是覆盖 closeEvent
并发送自定义信号。
class Window(QMainWindow):
closed = QtCore.pyqtSignal(object)
# ...
def new_window(self):
new_window = Window(self)
self.windows_list.append(new_window)
new_window.show()
new_window.closed.connect(self.window_list.remove)
def closeEvent(self, event):
self.closed.emit(self)
另一种可能性是始终设置 Qt.WA_DeleteOnClose
属性并连接到 destroyed
信号,但在这种情况下,您 不能 依赖信号参数(它与实际删除的 window 不匹配),并且必须使用带有 window 实例的 lambda 代替:
class Window(QMainWindow):
# ...
def new_window(self):
new_window = Window(self)
self.windows_list.append(new_window)
new_window.setAttribute(Qt.WA_DeleteOnClose)
new_window.show()
new_window.destroyed.connect(lambda: self.windows_list.remove(new_window))
请注意,我将 class 名称大写,因为 classes 不应使用小写名称。
您可以使用 closeEvent
:
import sys
from PyQt5.QtCore import pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import (
QMainWindow, QApplication, QPushButton, QVBoxLayout, QWidget
)
from PyQt5.QtGui import QCloseEvent
class window(QMainWindow):
closed = pyqtSignal(QMainWindow)
def __init__(self, parent=None):
super(window, self).__init__()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.HBOX = QVBoxLayout()
self.PB = QPushButton('open new window')
self.PB.clicked.connect(self.new_window)
self.HBOX.addWidget(self.PB)
self.centralWidget.setLayout(self.HBOX)
self.windows_list = []
def new_window(self):
new_window = window(self)
new_window.closed.connect(self.remove_window_from_list)
self.windows_list.append(new_window)
self.windows_list[-1].show()
print(self.windows_list)
@pyqtSlot(QMainWindow)
def remove_window_from_list(self, window: QMainWindow) -> None:
self.windows_list.remove(window)
print(self.windows_list)
@pyqtSlot(QCloseEvent)
def closeEvent(self, a0: QCloseEvent) -> None:
self.closed.emit(self)
super().closeEvent(a0)
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = window()
ex.show()
sys.exit(app.exec_())