[[ activeDiscount.description ]] I'm giving a [[ activeDiscount.discount ]]% discount on my books with the code [[ couponCode ]].

The Qt6 editions of my books are now available, supporting Python 3 with PyQt6 and PySide6.

Threads & Processes
Run concurrent tasks without impacting your UI

As your applications become more complex you may finding yourself wanting to perform long-running tasks, such as interacting with remote APIs or performing complex calculations. By default any code you write exists in the same thread and process, meaning your long-running code can actually block Qt execution and cause your Python GUI app to "hang". In this PyQt5 tutorial we'll cover how to avoid this happening and keep your applications running smoothly, no matter the workload.

Start with “Multithreading PyQt applications with QThreadPool”

Threads & Processes

Multithreading PyQt applications with QThreadPool

Run background tasks concurrently without impacting your UI

Using QProcess to run external programs

Run background programs without impacting your UI

Start now

Join the Community

I start with thanks to Martin Fitzpatrick for excellent explanation and code for running QRunnable objects within QThreadPool. My problem is that I have three separate processes where one of those is taking the results of the two as arguments. Of course I could combine them into on big function but as the result are stored in variable accessible for all the processes it is not necessary to run all of three processes every time.

So I start with Martin code that is used as class definition for QRunnable object and signals

class Worker(QtCore.QRunnable):
'''
Worker thread

Inherits from QRunnable to handler worker thread setup, signals and wrap-up.

:param callback: The function callback to run on this worker thread. Supplied args and
             kwargs will be passed through to the runner.
:type callback: function
:param args: Arguments to pass to the callback function

Then I am using a function which executes functions passed to that as arguments

    def exe_worker_run(self, WorkerPool, function, arguments):
        Worker = thread.Worker(function, arguments)
        Worker.signal.started.connect(self.sig_thread_start)
        Worker.signal.error.connect(self.sig_thread_error)
        Worker.signal.result.connect(self.sig_thread_result)
        Worker.signal.finished.connect(self.sig_thread_finish)
        WorkerPool.start(Worker)

The results are intercepted by the following function (of course it is simplified)

    def sig_thread_result(self, result):

Then the “function” argument in the exe_worker_run is the name of the function that performs the real job. Again the simplified version of that function will look like

    def exe_languages_load(self, arguments, callback_progress, callback_data):
        try:
            result = (sql query to database)
        except Exception as ex:
            session.rollback()
            print(ex)
        finally:
            session.close()
            return result

The problem is that the results of two functions which are then arguments for third are not emitted before the execution of third function is started. What should I do to allow sequential execution of all three functions in a way which will postpone the execution of third until the results of first and second are emitted and assigned to respective dataframes?