Search code examples
pythonmultithreadingprocesspyqtqthread

Start a function from a thread. (GUI thread and QThread errors)


I've made routine with Python's threading module to run a subprocess and wait for it to finish. I do the threading with the following line :

t1=Thread(target=self.routineFunction, args=(self, "file1.txt", "file2.txt", self.nextFunction)).start()

Inside my function routineFunction(self,file1,file2,nextFunction) I call the next function to run once the subprocess has finished running.

Everything works fine until then.

But if I create new QObject items in my next function, I receive a lot of errors : - "QPixmap: It is not safe to use pixmaps outside the GUI thread" - "QObject::startTimer: QTimer can only be used with threads started with QThread"

My guess is that when I call nextFunction from the routine it is ran in the same thread as the routine, hence the errors. Is there a way to call a function from the routine inside the "main" or "normal" thread ?.

Thank you for your help.


Solution

  • Generally, it is okay to call functions from other threads. But many GUI libraries (QT is among them) have some restrictions on this behavior.

    For example, there are designated thread called 'GUI thread' which handles all graphical stuff, like dispatching messages from OS, redrawing windows, etc. And you also restricted to work with GUI withing this only thread. So, for example, you should not create QPixmap in other threads.

    QTimer uses some QThread's internal data, so you should use such timers in threads only started with QThread, but not with plain Python thread module.

    Returning to your question, if you want ot work with QT, you should spawn your threads using QThread and post events to GUI thread using postEvent() method. This will guarantee consistence of QT internal data structures.

    So, you can ran your code in any QT thread, but if you want to work with GUI (your QObject uses QPixmap, so it is the case), you need to handle such calls only in GUI thread.