You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 16:24:59