首页 > 解决方案 > 将 QObject 和 QThread 多类化在一起

问题描述

我正在尝试创建一组状态机来处理我的 PyQt 项目中的不同任务,在处理需要在单个线程上处理图形的方式的过程中,我创建了两种类型的状态机,StateMachine其中必须继承QObjectand ThreadedStateMachine,为了避免重复代码,我已经从StateMachineand继承了QThread

这是我复制问题的最低限度完整代码:

from PyQt5.QtCore import QObject, QThread


class StateMachine(QObject):
    def __init__(self):
        super().__init__()


class ThreadedStateMachine(StateMachine, QThread):
    def __init__(self):
        super().__init__()


if __name__ == "__main__":
    t = ThreadedStateMachine()

我希望这可以正常工作,但我收到了这个异常

QObject::connect: No such signal ThreadedStateMachine::started()
Traceback (most recent call last):
  File "/snap/pycharm-community/132/helpers/pydev/pydevd.py", line 1758, in <module>
    main()
  File "/snap/pycharm-community/132/helpers/pydev/pydevd.py", line 1752, in main
    globals = debugger.run(setup['file'], None, None, is_module)
  File "/snap/pycharm-community/132/helpers/pydev/pydevd.py", line 1147, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/snap/pycharm-community/132/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/home/aaron/.PyCharmCE2019.1/config/scratches/emerson_pmd/new/scratch_7.py", line 15, in <module>
    t = ThreadedStateMachine()
  File "/home/aaron/.PyCharmCE2019.1/config/scratches/emerson_pmd/new/scratch_7.py", line 11, in __init__
    super().__init__()
  File "/home/aaron/.PyCharmCE2019.1/config/scratches/emerson_pmd/new/scratch_7.py", line 6, in __init__
    super().__init__()
  File "/snap/pycharm-community/132/helpers/pydev/_pydev_bundle/pydev_monkey_qt.py", line 181, in __init__
    self.started = StartedSignalWrapper(self, self.started)
  File "/snap/pycharm-community/132/helpers/pydev/_pydev_bundle/pydev_monkey_qt.py", line 151, in __init__
    self.original_started.connect(self._signal)
TypeError: connect() failed between started() and _signal()

QObject将和QThread类组合成一个对象的正确方法是什么?

笔记

我目前正在使用threading.Thread作为一种解决方法,但我希望能够QMessageBox从另一个线程启动一个,这会显示一个错误:

QObject::connect: Cannot queue arguments of type 'QItemSelection'
(Make sure 'QItemSelection' is registered using qRegisterMetaType().)
QBasicTimer::start: Timers cannot be started from another thread

我相信 usingQThread会在这里工作。

标签: pythonpyqtpyqt5qthreadqobject

解决方案


那么你有一个问题 PyQt 不允许 2 QObject 的双重继承,StateMachine 是一个 QObject 并且 QThread 也是一个 QObject(参见文档)。

我不认为问题是由 threading.Thread() 引起的,我怀疑这是因为您正在修改一些存在于线程中且不是线程安全的对象,QObjects 不是线程安全的,因此您必须进行交互将这些对象放在它们所在的线程中,并且模型是 QObject。

读:


推荐阅读