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

实例化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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 05:10:55