PySide6中Signal连接出现positional arguments错误问题排查
问题:PyQt5迁移PySide6时Signal连接报错
尝试将部分PyQt5代码迁移至PySide6,原代码适配PyQt5可正常运行,但在PySide6环境下执行报错。
原代码
#from PyQt5 import QtCore,QtWidgets #from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR from PySide6 import QtCore,QtWidgets from PySide6 import __version__ as PYQT_VERSION_STR from PySide6.QtCore import __version__ as QT_VERSION_STR class DynamicTupleSignal(QtCore.QObject): signal = QtCore.Signal(tuple) #signal = QtCore.pyqtSignal(tuple) def connect(self,func): self.signal.connect(func) def emit(self,data): self.signal.emit(data) class TestDynamicTupleSignal: dynsig=DynamicTupleSignal() def __init__(self): self.dynsig.connect(self.whattheheck) def whattheheck(self,data): print(data) if __name__ == "__main__": import sys print("Python Version",sys.version) print("PyQt5/PySide6 Version:",PYQT_VERSION_STR) print("Qt Version:",QT_VERSION_STR) app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QWidget() w.show() sig=TestDynamicTupleSignal() app.exec()
报错信息
Traceback (most recent call last): File "c:\data\src\test.py", line 42, in <module> sig=TestDynamicTupleSignal() File "c:\data\src\test.py", line 29, in __init__ self.dynsig.connect(self.whattheheck) File "c:\data\src\test.py", line 20, in connect self.signal.connect(func) TypeError: connect() takes 2 positional arguments but 4 were given
版本信息
Python Version 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] PySide6 Version: 6.5.1.1 Qt Version: 6.5.1 PyQt5 Version: 5.12.3 Qt Version: 5.12.10
问题分析与解决
这不是PySide6的bug,是你在QObject子类中定义的connect、emit方法和父类QObject的内置方法重名了。
QObject本身就自带connect和emit方法,你自定义的方法覆盖了父类的同名方法,导致调用self.signal.connect(func)时,实际执行的是你自己写的connect方法(而非Signal对象的connect方法),但你的方法仅接受2个参数,而Signal的connect调用时会传递更多参数,因此触发参数不匹配的错误。
解决方法很简单:修改自定义方法的名称,避免和QObject的内置方法冲突。比如将connect改为connect_slot,emit改为emit_data:
修改后的代码
from PySide6 import QtCore,QtWidgets from PySide6.QtCore import PYSIDE_VERSION_STR, QT_VERSION_STR class DynamicTupleSignal(QtCore.QObject): signal = QtCore.Signal(tuple) def connect_slot(self, func): self.signal.connect(func) def emit_data(self, data): self.signal.emit(data) class TestDynamicTupleSignal: dynsig=DynamicTupleSignal() def __init__(self): self.dynsig.connect_slot(self.whattheheck) def whattheheck(self,data): print(data) if __name__ == "__main__": import sys print("Python Version", sys.version) print("PySide6 Version:", PYSIDE_VERSION_STR) print("Qt Version:", QT_VERSION_STR) app = QtWidgets.QApplication(sys.argv) w = QtWidgets.QWidget() w.show() sig=TestDynamicTupleSignal() # 测试发射信号 sig.dynsig.emit_data(("测试内容", 123)) app.exec()
另外,建议直接使用PySide6官方提供的版本变量PYSIDE_VERSION_STR和QT_VERSION_STR,避免重命名导致混淆。
内容的提问来源于stack exchange,提问作者Torben
相关产品推荐
相关产品推荐

