[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..
-
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.
-
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
-
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