[SOLVED] Crash when Updating GUI from thread
-
I have the following code:
@
void MainWindow::first() {
QFuture<void> installerthread;
installerthread = QtConcurrent::run(this, &MainWindow::Installa);
}
void MainWindow::Installa() {
myClass bla=new myClass();
bla.work();
connect(bla,SIGNAL(finished(int)),this,SLOT(ProcessoFinito(int)), Qt::QueuedConnection);
}
void MainWindow::ProcessoFinito(int status){
this->ui->progressBar->setValue(1);
}
@The error which appears is QPixmap: It is not safe to use pixmaps outside the GUI thread
How can i solve this situation? I know that a GUI update from thread shouldn't happen,but there must be a solution!Solution: You can't update a QPixmap from thread! You should use another method..
-
You're going to need signals & slots.
-
Don't use pixmaps or drawing to the GUI from a thread that is not the GUI thread. The solution is to do the update from the main thread. Your code is not very clear to me though. You already have a signal/slot connection, and that is good, but I can't see if you use it correctly.
-
So to sum it up:
you are not allowed to update the GUI from a thread directly. You should use signals/slots to update the GUI instead. -
Take a look at how the Mandelbrot example in Qt uses signals/slots across thread boundaries to update the gui with an image calculated in the worker thread.
-
About the Mandelbrot example: drawing on QImages is perfectly safe in other threads, the only problem being font rendering (which may or may not be supported, QFontDatabase::supportsThreadedFontRendering tells you if it's the case). OTOH, QPixmaps are on the "server side", so can't be touched from any threads but the main thread.
http://doc.qt.nokia.com/4.7/threads-modules.html#painting-in-threads
-
But i am using signals and slot, why it have to crash?
-
Ahh, so do you think that updating QPixmap is not safe also with signal slot?
-
QPixmap cannot be touched in any thread other than the main thread.
-
Mar91: it all depends on how your threading setup works. You can trigger an update from another thread, if you have set it up correctly.
What does your worker class look like exactly. You did not, for intance subclass QThread directly and defined your signal on that subclass itself?
-
i didn't use real thread, but a simpler QFuturevoid :)
My class is a simply bunch of function, the critical function is the installer(), which has a list of .exe to execute, and i wanted to execute one by one, so i used the QProcess::waitforfinished(-1) ( Hangs until the QProcess has been completed ). I also could use the signal QProcess::finished(int), but then myclass would have been really hardcoded, because the signal had to trigger again the installer function until the list is empty, and i don't think is a good solution ( if you think is good, i am ready to remove thread , they are only causing me lot of problem :) ). Myclass inside has no thread or QFutureVoid, it has simply some signal\slot, nothing else :)
-
I think, I would remove the threading and go for the async solution you laid out, consecutively executing your processes and triggering the next iteration on QProcess::finished().
However, I don't see an obvious mistake in your current approach, other than a memory leak in you not destroying your bla instance.
-
But it's not my fault.. if you try to update a QPlainTextEdit it works without crash! As you can see from the link posted from peppe, QPixmap updating it's not allowed from thread! I must switch to the signal\slot method!
Thanks to everybody :)
You can mark has Solved i think -
Only because it does not crash does not mean it's correct.
If you see, the thread as solved, click edit on the first post and change the title, please