QThread updating a Widget in the GUI
-
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
-
@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. -
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)));
-
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 -
-
As @Dyami-Caliri said your program is not using the thread at all.
You are calling bothgenerateCoordinates()
andrepaint()
in the ui thread. There's no parallel execution here.