Not sure if I'm using QThread properly
-
Hello,
I'm using qml as my front end, and I connect it using signals and slots to the backend.
I have some data that I'm processing after selecting a file and my ui is frozen until that process is complete which is why I wanted to try and solve that using QThread.This is a simplified version of how I'm currently using it and it's not working for me (ui still frozen):
from functools import partial class Secondary(QObject): update_list = Signal() def __init__(self): QObject.__init__(self) def process_data(self, file): do stuff self.update_list.emit() class Main(QObject): def __init__(self): QObject.__init__(self) self.m_thread = QThread(self) self.m_thread.start() self.secondary = Secondary() self.secondary.moveToThread(self.m_thread) self.secondary.update_list.connect(method_to_update_list) @Slot() def load_file(self): wrapper = partial(self.secondary.process_data, file) QTimer.singleShot(0, wrapper)
The "load_file" method is called from the ui, and then the ui is frozen until "process_data" in the Secondary class is complete.
What am I missing? Or am I just not using it correctly at all?Thanks in advance
-
Add a signal to your MainWindow class, connect it to your worker object slot and emit it when appropriate.
-
Hi,
I am guessing that the "partial" short circuits the Qt connection detection and thus the slot is called in the main thread context.
-
Hi @SGaist,
I tried replacing the partial with either:
QTimer.singleShot(0, self.secondary, SLOT(self.secondary.process_data(file)))
Which runs successfully but gives me the following:
RuntimeWarning: MetaObjectBuilder::addMethod: Invalid method signature provided for ""
QTimer.singleShot(0, self.secondary, SLOT(self.secondary.process_data(file)))
qt.core.qobject.connect: QObject::connect: Parentheses expected, slot Secondary::Not sure exactly what it means or what I should do to avoid it.
Or:
QTimer.singleShot(0, lambda : self.secondary.process_data(file))
Both work but the ui is still frozen just like when I was using partial, so I'm kinda lost as to why this is not working.
-
Add a signal to your MainWindow class, connect it to your worker object slot and emit it when appropriate.
-
Add a signal to your MainWindow class, connect it to your worker object slot and emit it when appropriate.