PySide6 Signal/Slot异常:点击任意按钮均关窗口1(PyQt6正常)
PySide6与PyQt6按钮关闭父窗口行为不一致问题
我写了一段代码实现点击按钮关闭其父窗口:在PyQt6中点击对应按钮能正常关闭该按钮所在的父窗口,但在PySide6中,无论点击哪个按钮,始终只会关闭窗口1。请问这是代码错误还是PySide6的BUG?
PyQt6代码
from PyQt6.QtCore import pyqtSignal from PyQt6.QtWidgets import QWidget, QPushButton, QApplication, QVBoxLayout class MyWindow(QWidget): closed = pyqtSignal() def __init__(self, name): super().__init__() button = QPushButton(name) button.clicked.connect(self.closed.emit) layout = QVBoxLayout() layout.addWidget(button) self.setLayout(layout) app = QApplication([]) win1 = MyWindow("win1") win1.closed.connect(win1.close) win1.show() win2 = MyWindow("win2") win2.closed.connect(win2.close) win2.show() app.exec()
PySide6代码
from PySide6.QtCore import Signal from PySide6.QtWidgets import QWidget, QPushButton, QApplication, QVBoxLayout class MyWindow(QWidget): closed = Signal() def __init__(self, name): super().__init__() button = QPushButton(name) button.clicked.connect(self.closed.emit) layout = QVBoxLayout() layout.addWidget(button) self.setLayout(layout) app = QApplication([]) win1 = MyWindow("win1") win1.closed.connect(win1.close) win1.show() win2 = MyWindow("win2") win2.closed.connect(win2.close) win2.show() app.exec()
使用版本
- PySide 6.5.1
- PyQt 6.5.0
- Python 3.11.3
- 操作系统:Linux
这不是代码逻辑错误,是PySide6中Signal.emit方法的绑定特性导致的问题:直接将self.closed.emit作为槽函数传递时,它没有正确绑定到当前窗口实例的closed信号上,最终所有按钮的点击都会触发第一个创建的窗口(win1)的closed信号回调,所以无论点哪个按钮都只关win1。
解决方法很简单,不要直接连接emit方法,封装一个实例方法来触发信号:
from PySide6.QtCore import Signal from PySide6.QtWidgets import QWidget, QPushButton, QApplication, QVBoxLayout class MyWindow(QWidget): closed = Signal() def __init__(self, name): super().__init__() button = QPushButton(name) # 改用实例方法触发信号 button.clicked.connect(self.trigger_closed) layout = QVBoxLayout() layout.addWidget(button) self.setLayout(layout) def trigger_closed(self): self.closed.emit() app = QApplication([]) win1 = MyWindow("win1") win1.closed.connect(win1.close) win1.show() win2 = MyWindow("win2") win2.closed.connect(win2.close) win2.show() app.exec()
原理:PyQt6的pyqtSignal.emit会自动绑定到实例,但PySide6的Signal.emit作为回调传递时丢失了实例绑定。通过封装实例方法trigger_closed,确保每次调用的都是当前窗口实例的closed.emit(),就能正确触发对应窗口的关闭逻辑。
内容的提问来源于stack exchange,提问作者kleio12345
相关产品推荐
相关产品推荐

