一起对 QObject 和 QThread 进行多类化
Multiclassing QObject and QThread together
我正在尝试创建一组状态机来处理我的 PyQt 项目中的不同任务,在处理图形需要在单个线程上处理的方式的过程中,我创建了两种类型的状态机,一个必须继承 QObject
的 StateMachine
和一个 ThreadedStateMachine
,为了避免重复代码,我已经从 StateMachine
和 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
我相信在这里使用 QThread
会奏效。
你遇到了一个问题 PyQt 不允许双重继承 2 个 QObject,StateMachine 是一个 QObject,QThread 也是一个 QObject(参见 docs)。
我不认为问题是由 threading.Thread() 引起的,我怀疑这是因为您正在修改某个线程中的对象而不是 thread-safe,QObjects不是 thread-safe 所以你必须在它们所在的线程中与这些对象交互,模型是 QObject。
阅读:
我正在尝试创建一组状态机来处理我的 PyQt 项目中的不同任务,在处理图形需要在单个线程上处理的方式的过程中,我创建了两种类型的状态机,一个必须继承 QObject
的 StateMachine
和一个 ThreadedStateMachine
,为了避免重复代码,我已经从 StateMachine
和 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
我相信在这里使用 QThread
会奏效。
你遇到了一个问题 PyQt 不允许双重继承 2 个 QObject,StateMachine 是一个 QObject,QThread 也是一个 QObject(参见 docs)。
我不认为问题是由 threading.Thread() 引起的,我怀疑这是因为您正在修改某个线程中的对象而不是 thread-safe,QObjects不是 thread-safe 所以你必须在它们所在的线程中与这些对象交互,模型是 QObject。
阅读: