在PyQt5中,要实现点击按钮在主界面中弹出多个独立窗口,并监控这些窗口的状态(如是否被关闭),可以使用QMainWindow作为主窗口,并使用QDialog或QMainWindow(根据你的需求,如果子窗口也需要菜单等复杂功能,则使用QMainWindow)作为子窗口。每个子窗口可以通过信号将状态变化回传给主窗口。
以下是一个简单的示例,演示了如何实现这一功能:
主窗口类 (MainWindow):包含一个按钮,点击按钮会弹出新的子窗口。
子窗口类 (ChildWindow):继承自QDialog(或QMainWindow),包含关闭信号,当窗口关闭时发送信号。
在主窗口中监控子窗口的关闭:通过连接子窗口的关闭信号到主窗口的槽函数。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QVBoxLayout, QLabel
from PyQt5.QtCore import pyqtSignal, QEvent
class ChildWindow(QDialog):
closedSignal = pyqtSignal()
def __init__(self, parent=None):
super(ChildWindow, self).__init__(parent)
self.setWindowTitle("Child Window")
layout = QVBoxLayout()
label = QLabel("This is a child window.", self)
layout.addWidget(label)
self.setLayout(layout)
def closeEvent(self, event: QEvent):
# 在窗口关闭前发射信号
self.closedSignal.emit()
# 调用基类的closeEvent来实际关闭窗口
super(ChildWindow, self).closeEvent(event)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Main Window")
# 布局和按钮
self.button = QPushButton("Open Child Window", self)
self.button.clicked.connect(self.open_child_window)
self.setCentralWidget(self.button)
# 用于存储子窗口的列表
self.child_windows = []
def open_child_window(self):
child = ChildWindow(self)
child.closedSignal.connect(self.on_child_closed)
child.show()
self.child_windows.append(child)
def on_child_closed(self):
# 找出被关闭的子窗口并从列表中移除
for child in self.child_windows[:]:
if not child.isVisible():
self.child_windows.remove(child)
print(f"Child window closed.")
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
在这个修正后的代码中,ChildWindow
类重写了 closeEvent
方法,该方法在窗口关闭时会被调用。在这个方法中,我们首先发射了 closedSignal
信号,然后调用了基类 QDialog
的 closeEvent
方法来实际关闭窗口。
现在,每当一个子窗口关闭时,MainWindow
的 on_child_closed
方法就会被调用,并且相应的子窗口会从 self.child_windows
列表中移除。注意,这里我们仍然通过检查窗口的 isVisible()
方法来确定窗口是否已经被关闭,因为即使窗口已经关闭了,它的实例仍然存在于内存中,直到被垃圾回收。