0

Qt スレッドとそのシグナルに問題があります。dworker という QObject を作成して QThread に移動し、開始ボタンをクリックしてスレッドを開始します。基本的には、いくつかの数値で GUI を更新するだけで、停止ボタンを押すと停止するはずです。それは停止しますが、「qDebug() << "スレッド停止 = " << 停止;" in dworker が呼び出されず、再度開始できません。シグナルはトリガーされますが、スロットメソッドは実行されません。

メインウィンドウ.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;
}
4

1 に答える 1

0

問題がたくさん!

connect でデフォルト値を使用していますQt::AutoConnection。これは、宛先スレッドのイベント ループを介してスレッド間でシグナルが渡される場合、docを参照してください。これが、関数を停止できない理由です。実行中のイベントループは決して制御されませんslot_process()。これを修正するには、次のように接続を変更します (を使用Qt::DirectConnection):

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

別の問題: でミューテックスを誤ってロックしています。slot_process()ブレークはロック解除をスキップし、ミューテックスは永久にロックされたままになることに注意してください。次のように修正します。

{
    QMutexLocker locker(&mutex);
    if(stop) break;
} // braces are important
于 2013-08-14T12:22:40.587 に答える