Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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


  • Lifetime Qt Champion

    Add a signal to your MainWindow class, connect it to your worker object slot and emit it when appropriate.


  • Lifetime Qt Champion

    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.


  • Lifetime Qt Champion

    Add a signal to your MainWindow class, connect it to your worker object slot and emit it when appropriate.



  • @SGaist Thanks!
    I implemented Signal/Slot like you suggested and it's working great now without even needing QTimer.


Log in to reply