PySide2多窗口变量传递:实现窗口关闭时返回值的方法
PySide2实现关闭窗口时向主窗口返回值的几种方案
要实现子窗口关闭时把设置的值同步到主窗口,下面提供几种符合Qt设计逻辑的常用方案,基于你的代码修改:
方案1:自定义信号(推荐,解耦性强)
这种方式是Qt的标准做法,不管子窗口是模态还是非模态都能正常工作,还能避免主窗口和子窗口的强耦合。
修改要点:
- 在子窗口
AnotherWindow中定义一个自定义信号,用来传递要同步的值 - 在子窗口的
send方法(或关闭事件)中发射信号,再关闭窗口 - 主窗口连接子窗口的信号到自己的处理函数,更新显示
修改后的完整代码:
from PySide2.QtCore import * from PySide2.QtGui import * from PySide2.QtWidgets import * import sys class AnotherWindow(QWidget): # 定义自定义信号,指定传递字符串类型的值 value_sent = Signal(str) def __init__(self): super().__init__() self.setGeometry(QRect(300, 300, 300, 100)) self.lcd = QSpinBox() self.btn = QPushButton("Send") self.btn.clicked.connect(self.send) layout = QVBoxLayout() layout.addWidget(self.lcd) layout.addWidget(self.btn) self.setLayout(layout) def send(self): t = self.lcd.text() # 发射信号传递值 self.value_sent.emit(t) self.close() # 可选:如果点击窗口右上角的关闭按钮也要同步值,重写closeEvent def closeEvent(self, event): t = self.lcd.text() self.value_sent.emit(t) event.accept() class MainWindow(QWidget): def __init__(self): super().__init__() self.resize(200, 100) self.lcd = QLCDNumber() self.btn = QPushButton("New Window") self.btn.clicked.connect(self.open_new) layout = QVBoxLayout() layout.addWidget(self.lcd) layout.addWidget(self.btn) self.setLayout(layout) def open_new(self): self.new_window = AnotherWindow() # 连接子窗口的信号到更新显示的函数 self.new_window.value_sent.connect(self.update_display) self.new_window.show() def update_display(self, value): # 把接收到的值显示到主窗口的LCD上 self.lcd.display(value) def main(): app = QApplication(sys.argv) window = MainWindow() window.show() app.exec_() if __name__ == "__main__": main()
方案2:模态窗口+实例属性
如果子窗口不需要和主窗口同时操作,可以用模态窗口的方式。模态窗口打开后会阻塞主窗口操作,关闭后直接读取子窗口的属性就能拿到值。
修改要点:
- 子窗口中新增一个实例属性保存要传递的值
- 主窗口用
exec_()打开模态窗口,关闭后直接读取该属性
修改后的完整代码:
from PySide2.QtCore import * from PySide2.QtGui import * from PySide2.QtWidgets import * import sys class AnotherWindow(QWidget): def __init__(self): super().__init__() self.setGeometry(QRect(300, 300, 300, 100)) self.result_value = "" # 用来保存结果的实例属性 self.lcd = QSpinBox() self.btn = QPushButton("Send") self.btn.clicked.connect(self.send) layout = QVBoxLayout() layout.addWidget(self.lcd) layout.addWidget(self.btn) self.setLayout(layout) def send(self): self.result_value = self.lcd.text() self.close() # 可选:处理关闭按钮的情况 def closeEvent(self, event): self.result_value = self.lcd.text() event.accept() class MainWindow(QWidget): def __init__(self): super().__init__() self.resize(200, 100) self.lcd = QLCDNumber() self.btn = QPushButton("New Window") self.btn.clicked.connect(self.open_new) layout = QVBoxLayout() layout.addWidget(self.lcd) layout.addWidget(self.btn) self.setLayout(layout) def open_new(self): self.new_window = AnotherWindow() # 以模态方式打开窗口,exec_()会阻塞直到窗口关闭 self.new_window.exec_() # 窗口关闭后读取结果并更新显示 self.lcd.display(self.new_window.result_value) def main(): app = QApplication(sys.argv) window = MainWindow() window.show() app.exec_() if __name__ == "__main__": main()
方案3:非模态窗口+销毁信号
如果子窗口需要保持非模态(主窗口可同时操作),可以连接子窗口的destroyed信号,在窗口销毁时读取其属性值。
修改后的完整代码:
from PySide2.QtCore import * from PySide2.QtGui import * from PySide2.QtWidgets import * import sys class AnotherWindow(QWidget): def __init__(self): super().__init__() self.setGeometry(QRect(300, 300, 300, 100)) self.result_value = "" self.lcd = QSpinBox() self.btn = QPushButton("Send") self.btn.clicked.connect(self.send) layout = QVBoxLayout() layout.addWidget(self.lcd) layout.addWidget(self.btn) self.setLayout(layout) def send(self): self.result_value = self.lcd.text() self.close() def closeEvent(self, event): self.result_value = self.lcd.text() event.accept() class MainWindow(QWidget): def __init__(self): super().__init__() self.resize(200, 100) self.lcd = QLCDNumber() self.btn = QPushButton("New Window") self.btn.clicked.connect(self.open_new) layout = QVBoxLayout() layout.addWidget(self.lcd) layout.addWidget(self.btn) self.setLayout(layout) def open_new(self): self.new_window = AnotherWindow() # 连接窗口销毁信号到处理函数 self.new_window.destroyed.connect(self.on_window_closed) self.new_window.show() def on_window_closed(self): # 读取子窗口保存的结果值并更新显示 self.lcd.display(self.new_window.result_value) def main(): app = QApplication(sys.argv) window = MainWindow() window.show() app.exec_() if __name__ == "__main__": main()
内容的提问来源于stack exchange,提问作者AnnAc0nda
相关产品推荐
相关产品推荐

