实例化QThread对象时如何传递变量?PySide6类型错误求助
PySide6中给QThread传递变量的正确方法
问题描述
尝试给QThread子类传递变量时出现如下类型错误:
Traceback (most recent call last): File "C:\Users\joe\python\ThreadTest.py", line 22, in start_thread instanced_thread = WorkerThread(self, 'c:\testfile.xml') File "C:\Users\joe\python\ThreadTest.py", line 44, in __init__ QThread.__init__(self, parent) TypeError: 'PySide6.QtCore.QThread.__init__' called with wrong argument types: PySide6.QtCore.QThread.__init__(str) Supported signatures: PySide6.QtCore.QThread.__init__(Optional[PySide6.QtCore.QObject] = None)
使用环境:PySide6 + Python 3.9.10
原代码如下:
# Copyright (C) 2022 The Qt Company Ltd. # SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import sys from PySide6.QtCore import QObject, QThread, Signal, Slot from PySide6.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget # Create a basic window with a layout and a button class MainForm(QWidget): def __init__(self): super().__init__() self.setWindowTitle("My Form") self.layout = QVBoxLayout() self.button = QPushButton("Click me!") self.button.clicked.connect(self.start_thread) self.layout.addWidget(self.button) self.setLayout(self.layout) # Instantiate and start a new thread def start_thread(self): instanced_thread = WorkerThread(self, 'c:\testfile.xml') instanced_thread.start() # Create the Slots that will receive signals @Slot(str) def update_str_field(self, message): print(message) @Slot(int) def update_int_field(self, value): print(value) # Signals must inherit QObject class MySignals(QObject): signal_str = Signal(str) signal_int = Signal(int) # Create the Worker Thread class WorkerThread(QThread): def __init__(self, filename, parent=None): QThread.__init__(self, parent) # Instantiate signals and connect signals to the slots self.signals = MySignals() self.signals.signal_str.connect(parent.update_str_field) self.signals.signal_int.connect(parent.update_int_field) self.filename = filename def run(self): # Do something on the worker thread a = 1 + 1 # Emit signals whenever you want self.signals.signal_int.emit(a) self.signals.signal_str.emit("This text comes to Main thread from our Worker thread.") print(self.filename) if __name__ == "__main__": app = QApplication(sys.argv) window = MainForm() window.show() sys.exit(app.exec())
问题原因
WorkerThread的__init__方法参数顺序错误:实例化时传入的第一个参数是父对象self,第二个是文件名,但__init__定义的参数顺序是(self, filename, parent=None),导致父对象被赋值给filename,文件名被赋值给parent。而QThread构造函数只接受QObject类型的父对象,因此抛出类型错误。
修复方案
1. 调整线程类的参数顺序(推荐)
将parent参数放在filename前面,符合Qt类的常规设计:
# Create the Worker Thread class WorkerThread(QThread): def __init__(self, parent=None, filename=None): QThread.__init__(self, parent) self.signals = MySignals() # 增加父对象判空,避免空指针 if parent: self.signals.signal_str.connect(parent.update_str_field) self.signals.signal_int.connect(parent.update_int_field) self.filename = filename def run(self): a = 1 + 1 self.signals.signal_int.emit(a) self.signals.signal_str.emit("This text comes to Main thread from our Worker thread.") if self.filename: print(self.filename)
2. 修正路径字符串
原路径'c:\testfile.xml'中的\t会被解析为制表符,需修改为以下两种形式之一:
# 双反斜杠转义 instanced_thread = WorkerThread(self, 'c:\\testfile.xml') # 原始字符串 instanced_thread = WorkerThread(self, r'c:\testfile.xml')
核心要点
- 给QThread子类传递变量时,需保证
__init__方法的参数顺序正确,父对象参数通常放在首位 - 在
__init__中将自定义变量保存为实例属性,供run方法调用 - 连接信号前需判空,避免父对象为None时出现错误
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

