Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] Accessing UI from QtConcurrent::run
QtWS25 Last Chance

[SOLVED] Accessing UI from QtConcurrent::run

Scheduled Pinned Locked Moved General and Desktop
multithreadsqtconcurrent
4 Posts 2 Posters 3.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    Chick3nN00dleS0up
    wrote on last edited by Chick3nN00dleS0up
    #1

    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!

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #2

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

      C 1 Reply Last reply
      1
      • ? A Former User

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

        C Offline
        C Offline
        Chick3nN00dleS0up
        wrote on last edited by
        #3

        @Wieland Thank you, it worked! :)

        ? 1 Reply Last reply
        0
        • C Chick3nN00dleS0up

          @Wieland Thank you, it worked! :)

          ? Offline
          ? Offline
          A Former User
          wrote on last edited by
          #4

          @Chick3nN00dleS0up You're welcome :-)

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved