Congratulations to our 2022 Qt Champions!

[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
            struct timespec ts = { delay_ms / 1000, (delay_ms % 1000) * 1000 * 1000 };
            nanosleep(&ts, NULL);

    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->drawEllipse(QRect(10, 1, 18, 18));
        painter->setPen(QPen(this->getColor(), 2, Qt::SolidLine, Qt::SquareCap));
        painter->drawEllipse(QRect(10, 1, 18, 18));

    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 :-)