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
QtWS: Super Early Bird Tickets Available!

QThread updating a Widget in the GUI

Scheduled Pinned Locked Moved General and Desktop
qthreadsignalslot
7 Posts 4 Posters 11.8k 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 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 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
    1
  • S Offline
    S Offline
    sleroux
    replied to mcosta on 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 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
    0
  • D Offline
    D Offline
    Dyami Caliri
    wrote on 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
  • S Offline
    S Offline
    sleroux
    replied to mcosta on 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 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

  • Login

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