简体   繁体   中英

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.

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.

Ok so I think that werewindle solution is possible. Unfortunatly, I found it difficult to convert my current script from Thread to QThread (I am new to threading in general).

I found a workaround : Instead of passing nextFunction as an argument, I pass a queue = Queue.Queue() and I use queue.put(True) if my subprocess in my new thread is a success. There is no more nextFunction, I simply wait for a value in the queue with queue.get(). By doing this, I can then continue in the GUI thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM