简体   繁体   中英

Multiclassing QObject and QThread together

I'm trying to create a set of state machines to handle different tasks in my PyQt project, in the process of handling the way that graphics need to be handled on a single thread, I've created two types of state machines, a StateMachine which must inherit QObject and a ThreadedStateMachine which, to avoid duplicate code, I've had inherit from both StateMachine and QThread .

Here is my minimally complete code to replicate the problem:

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()

I expected this to work without fail, but instead I receive this exception

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()

What's the correct way to combine the QObject and QThread classes into a single object?

Note

I am currently using threading.Thread as a workaround, but I'd like to be able to launch a QMessageBox from the other thread, which shows an error:

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

I believe that using QThread would work here.

Well you have a problem PyQt does not allow the double inheritance of 2 QObject, StateMachine is a QObject and QThread is also a QObject(see the docs ).

I do not think the problem is caused by threading.Thread(), I suspect that this is caused because you are modifying some object that lives in a thread and is not thread-safe, the QObjects are not thread-safe so you must interact with those objects in the thread where they live, and the models are QObject.

Read:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM