Reputation: 23896
Main (function main is there) thread of my program is reserved for non-GUI tasks. It calls a number of lengthy calculation functions. All implemented GUI's have been doing their work in a separate threads.
I'm now going to implement one more GUI using Qt. Qt documentation says all GUI related tasks should be done in main thread. In my case, inserting occasional QCoreApplication::processEvents() calls in main thread would be virtually useless due to great delays between them.
Is there any way to overcome this constraint of Qt? Is it impossible to do something non-GUI related in main thread of Qt program?
Upvotes: 31
Views: 34323
Reputation: 198
The concept of main thread is not clearly defined in Qt documentation. Actually, the main thread of a process (process that executes the Process.run function) can be different from the main Qt thread (thread that instantiates the first Qt object like a QApplication), although both "main" threads are often the same one.
Example of valid code structure:
function below will run in the process' non-main thread 'thread-1', that will become immediately Qt's main thread.
def startThread1():
app = QApplication(sys.argv)
app.exec_() # enter event loop
code below run in process' main thread, not to be confused with the main Qt and unique GUI thread of the process.
thread1 = Thread(target=self.startThread1)
thread1.start()
input('I am busy until you press enter')
Upvotes: 1
Reputation: 24902
It's best to offload the long computations onto other threads so the main GUI thread remains responsive. The old-school uniprocessing way of doing things would be be to make sure your computations never run for too long without polling GUI event handler, but that doesn't scale to multi-cores.
Fortunately Qt has excellent threading support. In the past you'd have to roll-you-own system for e.g farming out tasks to a thread-pool using QThread
, QMutex
, QWaitCondition
etc, but recent Qt releases have made things easier with higher level abstractions like QThreadPool
, QtConcurrent::run
and QFuture
.
Upvotes: 7
Reputation: 11808
No, you should be doing your calculations in a separate thread. As you already mentioned, there is a work-around available in QCoreApplication::processEvents()
, but it sounds like you're unable to make that work for you.
If you don't want to have to do all the work of setting up a QThread and moving all your code, you may find that the QtConcurrent::run function is useful - it allows you to run a function asynchronously.
A few pointers: You should try and keep your main (GUI) thread as light as possible. Large amounts of IO or calculations should either be done asynchronously using QtConcurrent::run, or run inside a separate QThread. Depending on the complexity of your code, you may be able to get away with the QtConcurrent method.
Upvotes: 33
Reputation: 25680
I don't know how things will go if you call QApplication::exec() from another thread, which then becomes your gui thread. Just an idea.
(Let us know if it works, it'd be interesting...)
Upvotes: 0