[SOLVED] Accessing UI from QtConcurrent::run
-
In my "DelayedRespondingBlock" I try to execute a method delayed without delaying the whole application, so I multithread and make the new thread sleeping for a little time:
void DelayedRespondingBlock::updateOutputs() //called from another class { QFuture<void> future = QtConcurrent::run(this, &DelayedRespondingBlock::doUpdateOutputs); } void DelayedRespondingBlock::doUpdateOutputs() { #ifdef Q_OS_WIN Sleep(uint(delay_ms)); #else struct timespec ts = { delay_ms / 1000, (delay_ms % 1000) * 1000 * 1000 }; nanosleep(&ts, NULL); #endif this->produceOutputValues(); }
This code works perfectly.
I derive "LedBlock" from DelayedRespondingBlock and implement produceOutputValues():void LedBlock::produceOutputValues() { this->repaint(); //paintEvent() checks some booleans }
delay_ms is 1000 for LedBlock.
After those 1000 ms, produceOutputValues() is called, so this->repaint() is called and the QWidget-class does some stuff, and finally my paintEvent() is called:void LedBlock::paintEvent(QPaintEvent *event) { QPainter* painter = new QPainter(this); painter->eraseRect(QRect(QPoint(0,0), QPoint(this->size().width(), this->size().height()))); if(this->getInputSockets().at(0)->getValue() == true) { painter->setBrush(QBrush(this->illuminationColor,Qt::SolidPattern)); painter->drawEllipse(QRect(10, 1, 18, 18)); } painter->setPen(QPen(this->getColor(), 2, Qt::SolidLine, Qt::SquareCap)); painter->drawEllipse(QRect(10, 1, 18, 18)); painter->end(); }
There are some more steps after my paintEvent is finished, but after that, I crash.
How am able to repaint my Widget from another Thread, without making it crash? Thanks in advance! -
Hi,
painting can only be done in the GUI thread. You could send a Qt signal from your worker thread to the GUI thread to trigger the repaint (signals/slots are thread safe). -
@Wieland Thank you, it worked! :)
-
@Chick3nN00dleS0up You're welcome :-)