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. QThread updating a Widget in the GUI

QThread updating a Widget in the GUI

Scheduled Pinned Locked Moved General and Desktop
qthreadsignalslot
7 Posts 4 Posters 11.9k 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.
  • S Offline
    S Offline
    sleroux
    wrote on 23 Mar 2015, 10:58 last edited by
    #1

    Good day

    I am writing an application which has to update a QLable with info from a QThread in real time. I am stuck at the point where only the last emit is received by the QLable, for some reason. Here is my code:

    #ifndef RANDWALK_H
    #define RANDWALK_H
    
    #include <QThread>
    #include <QStringList>
    #include <QTime>
    #include <QDebug>
    
    class RandWalk : public QThread
    {
        Q_OBJECT
    public:
        RandWalk();
    
    public slots:
        void generateCoordinates(int steps, QStringList start);
    
    signals:
        void message(QString);
    
    private:
        int x;
        int y;
    
    };
    
    #endif // RANDWALK_H
    
    #include "randwalk.h"
    
    RandWalk::RandWalk()
    {
    }
    
    void RandWalk::generateCoordinates(int steps, QStringList start)
    {
        int startX = start.at(0).toInt();
        int startY = start.at(1).toInt();
        QTime time = QTime::currentTime();
        int seed = time.msec();
        QStringList rList;
        qsrand(seed);
        for(int i = 0; i < steps; i++)
        {
            rList << QString::number(qrand() + startX) + ", " +
                     QString::number(qrand() + startY);
            qDebug() << rList.at(i);
            emit message(rList.at(i));
            this->sleep(1);
        }
    }
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        walker1 = new RandWalk;
        walker1->start();
        connect(walker1, SIGNAL(message(QString)), ui->locationLbl, SLOT(setText(QString)));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_goBtn_clicked()
    {
        QStringList start1;
        start1 << ui->xLedt->text() << ui->yLedt->text();
        walker1->generateCoordinates(10, start1);
    }
    `
    
    Your help will be much appreciated.
    
    Thank you
    1 Reply Last reply
    0
    • M Offline
      M Offline
      mcosta
      wrote on 23 Mar 2015, 11:04 last edited by
      #2

      Usually Qt tries to "compact" the refresh requests; this is to avoid flickering.

      You could try to manually call QWidget::repaint() in a slot

      Once your problem is solved don't forget to:

      • Mark the thread as SOLVED using the Topic Tool menu
      • Vote up the answer(s) that helped you to solve the issue

      You can embed images using (http://imgur.com/) or (http://postimage.org/)

      S 1 Reply Last reply 23 Mar 2015, 11:40
      1
      • M mcosta
        23 Mar 2015, 11:04

        Usually Qt tries to "compact" the refresh requests; this is to avoid flickering.

        You could try to manually call QWidget::repaint() in a slot

        S Offline
        S Offline
        sleroux
        wrote on 23 Mar 2015, 11:40 last edited by sleroux
        #3

        @mcosta
        Thanks for the reply. I am not sure that this is the problem, because I have increased the sleep intervals in my iteration in the Thread to 5 seconds, and the label still only updates on the last one.
        Also, there is no place to call repaint() from, in my current program structure. What I mean is that the signal is emitted from the walker object, which also dictates the intervals.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          mcosta
          wrote on 23 Mar 2015, 12:36 last edited by
          #4

          I suggest to create a custom slot in you class and call setText and repaint from there; in that way you can be able to detect how often the signal is received

          void MainWindow::mySlot(const QString &text)
          {
              qDebug() << Q_FUNC_INFO;
              ui->locationLbl->setText(text);
              ui->locationLbl->repaint();
          }
          
          connect(walker1, SIGNAL(message(QString)), this, SLOT(mySlot(QString)));
          

          Once your problem is solved don't forget to:

          • Mark the thread as SOLVED using the Topic Tool menu
          • Vote up the answer(s) that helped you to solve the issue

          You can embed images using (http://imgur.com/) or (http://postimage.org/)

          S 1 Reply Last reply 26 Mar 2015, 05:12
          0
          • D Offline
            D Offline
            Dyami Caliri
            wrote on 23 Mar 2015, 15:50 last edited by
            #5

            It looks like your RandWalk thread isn't actually running. You are calling generateCoordinates() from the GUI thread, so it's holding up the program there. That explains why you only see the last update.

            The QThread documentation shows a couple different ways to do work in another thread:
            http://doc.qt.io/qt-5/qthread.html

            1 Reply Last reply
            0
            • M mcosta
              23 Mar 2015, 12:36

              I suggest to create a custom slot in you class and call setText and repaint from there; in that way you can be able to detect how often the signal is received

              void MainWindow::mySlot(const QString &text)
              {
                  qDebug() << Q_FUNC_INFO;
                  ui->locationLbl->setText(text);
                  ui->locationLbl->repaint();
              }
              
              connect(walker1, SIGNAL(message(QString)), this, SLOT(mySlot(QString)));
              
              S Offline
              S Offline
              sleroux
              wrote on 26 Mar 2015, 05:12 last edited by sleroux
              #6

              @mcosta
              Good day
              Apologies for only replying now - we had an internet outage...
              Just after my last reply I tried your previous suggestion (to manually call QWidget::repaint() ) out a bit more, and it worked.
              Thank you very much!

              1 Reply Last reply
              0
              • Chris KawaC Offline
                Chris KawaC Offline
                Chris Kawa
                Lifetime Qt Champion
                wrote on 26 Mar 2015, 06:31 last edited by
                #7

                As @Dyami-Caliri said your program is not using the thread at all.
                You are calling both generateCoordinates() and repaint() in the ui thread. There's no parallel execution here.

                1 Reply Last reply
                0

                1/7

                23 Mar 2015, 10:58

                • Login

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