0

My QThread counter crashes giving odd results for what the number should be as the Thread counts properly but in the SetLabel function I get a different number to whats in the QThread ands it then crashes after 3 seconds and the label doesnt seem to update.

QThread* CountThread = new QThread;
Counter* Count = new Counter();
Count->moveToThread(CountThread);
connect(CountThread, SIGNAL(started()), Count, SLOT(Process()));
connect(Count, &Counter::SecondsUpdate, this, [=]{ SetLabel(Count->Seconds) ;});
connect(Count, SIGNAL(finished()), CountThread, SLOT(quit()));
CountThread->start();


void Counter::Process()
{
int secs = 0;
while (secs < 1000)
{
    qDebug() << "hello" << secs;
    secs += 1;
    Sleep(1000);
    emit SecondsUpdate();
}
emit finished();
}


void BaseWindow::SetLabel(int Seconds)
{
qDebug() << Seconds;
this->Test->setText(QString("Seconds: " + QString::number(Seconds)));
}

class Counter : public QObject
{
Q_OBJECT
public slots:
    void Process();

signals:
    void finished();
    void SecondsUpdate();

public:
    int getValue() { return Seconds;}
    int Seconds;

};

EDIT: The issue seems to lie in the changing of the label as I commented this->Text->setText out and it didnt crash

mrdeadguy34
  • 85
  • 1
  • 8

2 Answers2

1

The code shown has two basic problems.

  1. Counter::Seconds is never initialized/updated.
  2. Having moved Count to a new QThread you continue to access it from the main thread.

You could solve both of these by getting rid of the Seconds member and just passing the local counter secs as a parameter to the Counter::SecondsUpdate signal...

class Counter: public QObject
{
  Q_OBJECT;
public slots:
  void Process();
signals:
  void finished();
  void SecondsUpdate(int seconds);
public:
};

void Counter::Process ()
{
  int secs = 0;
  while (secs < 1000)
  {
    qDebug() << "hello" << secs;
    secs += 1;

    /*
     * Sleep(1000) --> QThread::sleep(1)
     */
    QThread::sleep(1);

    /*
     * Pass secs as a parameter to the SecondsUpdate signal.
     */
    emit SecondsUpdate(secs);
  }
  emit finished();
}

Then, change the relevant connect call from...

connect(Count, &Counter::SecondsUpdate, this, [=]{ SetLabel(Count->Seconds) ;});

to...

connect(Count, &Counter::SecondsUpdate, this, &BaseWindow::SetLabel);
G.M.
  • 12,232
  • 2
  • 15
  • 18
  • change `connect(Count, &Counter::SecondsUpdate, this, [=](int seconds) { SetLabel(seconds); });` to `connect(Count, &Counter::SecondsUpdate, this, &BaseWindow::SetLabel)`, is more elegant – eyllanesc Jul 01 '18 at 10:52
  • Thanks for your reply. Looks great to me! – mrdeadguy34 Jul 01 '18 at 14:32
0

Fixed by passing through the label as a pointer and edited it in the function.

mrdeadguy34
  • 85
  • 1
  • 8