0
votes

I have a problem with my Qt Thread and it's signals. I'm creating a QObject called dworker and move it to a QThread and then start the thread with a click on my start button. It's basicly just updating the GUI with some numbers and is supposed to stop when i press the stop button. Well it stops but the "qDebug() << "thread stopping = " << stop;" in dworker isn't called and i can't start it again. The signal is triggert but the slot methode isn't executed.

mainwindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

namespace GLOBAL
{
    Settings mSettings;
    Data mData;
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    dthread = new QThread(this);
   dworker = new Dworker();
   dworker->moveToThread(dthread);

    connect(dworker, SIGNAL(set_values(double,double,double,double,double,double)),
            this, SLOT(slot_set_values(double,double,double,double,double,double)));
    connect(ui->startButton, SIGNAL(clicked()), dworker, SLOT(slot_process()));
    connect(ui->stopButton, SIGNAL(clicked()), dworker, SLOT(slot_end_process()));

    dthread->start();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::slot_set_values(double ptm_temp, double ptm_hv, double heat_temp, double nomtemp, double current, double voltage)
{
    ui->pmtValueLabel->setText(QString::number(ptm_temp));
    ui->hvValueLabel->setText(QString::number(ptm_hv));
    ui->heatValueLabel->setText(QString::number(heat_temp));
    ui->nomValueLabel->setText(QString::number(nomtemp));
    ui->currenValueLabel->setText(QString::number(current));
    ui->vValueLabel->setText(QString::number(voltage));

    //qDebug() <<"set_values SLOT " <<ptm_temp<<" "<<ptm_hv<<" "<<heat_temp<<" "<<nomtemp<<" "<<current<<" "<<voltage;

}

void MainWindow::on_startButton_clicked()
{

}

void MainWindow::on_stopButton_clicked()
{
    dworker->stop = true;
    qDebug() << "send stop";
}

dworker.cpp:

#include "dworker.h"

using namespace GLOBAL;

QMutex mutex;

Dworker::Dworker(QObject *parent) :
    QObject(parent)
{

}

void Dworker::slot_process()
{
    stop = false;

    while (true)
    {

        mutex.lock();
        if(stop) break;
        mutex.unlock();

        qsrand(QDateTime::currentDateTime().toTime_t());
        mData.set_pmt_temp(qrand()%100);
        mData.set_pmt_hv(qrand()%100);
        mData.set_heat_opt_temp(qrand()%100);
        mData.set_heat_nominal_temp(qrand()%100);

        double pmt_tmp = mData.get_pmt_temp();
        double hv = mData.get_pmt_hv();
        double heat_temp = mData.get_heat_opt_temp();
        double heat_nom = mData.get_heat_nominal_temp();

        emit set_values(pmt_tmp,hv,heat_temp,heat_nom,0,0);

        QThread::msleep(1000);
        qDebug() <<"Thread SIGNAL " <<pmt_tmp<<" "<<hv<<" "<<heat_temp<<" "<<heat_nom;
    }
}

void Dworker::slot_end_process()
{
    mutex.lock();
    stop = true;
    mutex.unlock();

    qDebug() << "thread stopping = " << stop;
}
1
I suggest you read this.thuga

1 Answers

0
votes

Lots of problems!

You are using default value in connect Qt::AutoConnection. This means that if signal is passed between treads through event loop of destination thread, see doc. This is why you can't stop your function, your event loop is never gains control when slot_process() is running. To fix it change connect like this (use Qt::DirectConnection):

connect(ui->stopButton, SIGNAL(clicked()), 
        dworker, SLOT(slot_end_process())
        Qt::DirectConnection);

Another problem: you are locking mutex incorrectly in slot_process(), note that break will skip unlock and mutex will remain locked permanently, fix it like this:

{
    QMutexLocker locker(&mutex);
    if(stop) break;
} // braces are important