RPDeshaies
RPDeshaies

Reputation: 1874

Start a new thread in Python with a callback method in Main Thread for PyQT application

Situation :

I'm C#/JS developper and I'm new to Python. I'm developping a application using Python 2.7 and PyQT 4

In my main Window, I'm calling a method that is taking at least 15 seconds to execute.

This method is blocking my main thread and this is a problem for me because I want the user to be able to move the window even if the program is running calculation.

So I thought about using thread but I want to be able to be notified when the thread has finished it's job to refresh the data on the window.

If I call a new function in the created thread, it will create a new thread and it is nos permitted to modify the QT GUI from a different thread than the Main one.

Question :

Is there a way to start a new Thread (not a process) that will run a method and call another method from the Main Thread once the process is over ?

Clearly, I want to be able to have a equivalence to the JavaScript.jQuery.ajax() in a Python Environnement.

Upvotes: 4

Views: 4708

Answers (1)

You need to use QThread and signal and slots. QThread inherits from QObject, which allows to emit signals.

Upon the completion of the task, the QThread will emit a finished() signal

Edit

If you define a custom Thread like this:

class CustomThread(QtCore.QThread):
    def __init__(self, target, slotOnFinished=None):
        super(CustomThread, self).__init__()
        self.target = target
        if slotOnFinished:
            self.finished.connect(slotOnFinished)

    def run(self, *args, **kwargs):
        self.target(*args, **kwargs)

You will be able to do:

class MyCustomWidget(QtGui.QWidget):

    def __init__(self, parent=None):
        super(MyCustomWidget, self).__init__(parent)
        layout = QtGui.QVBoxLayout(self)
        button = QtGui.QPushButton("Start", self)
        layout.addWidget(button)    
        button.clicked.connect(self.onStart)
        self.actionthread = CustomThread(target=self.longAction, self.onFinished)

    def onFinished(self):
        # Do Something

    def longAction(self):
        time.sleep(3)

    def onStart(self): 
        self.actionthread.start()

Upvotes: 3

Related Questions