Qt - Contoh sederhana menggunakan thread yang dikontrol dengan tombol tekan

Saya telah mencoba agar contoh sederhana ini menggunakan utas yang diaktifkan dengan tombol agar berfungsi. Ini didasarkan pada solusi pada pertanyaan di bawah ini:

Cara menerapkan seringnya start/stop thread (QThread )

Perbedaan utama antara contoh solusi di atas dan kode saya di bawah ini adalah:

  1. Saya menggunakan QWidget, bukan MainWindow
  2. Saya mengubah nama sinyal untuk kejelasan
  3. Kode saya berisi informasi debug
  4. Saya bereksperimen dengan menghilangkan sinyal yang dibuat oleh pekerja karena tampaknya tidak melakukan apa pun

Tampaknya sinyal start/stop tidak memicu slot yang sesuai, namun saya tidak cukup berpengalaman untuk memecahkan masalahnya.

Selain itu, saya tidak yakin dengan tujuan sinyal tersebut:

SignalToObj_mainThreadGUI()

Apakah itu hanya sesuatu yang bisa digunakan dan tidak?

Saya telah mencoba agar kode ini berfungsi selama beberapa waktu, jadi bantuan apa pun akan sangat kami hargai.

main.cpp

#include "threadtest.h"
#include <QApplication>

int main(int argc, char *argv[]) 
{
    QApplication a(argc, argv);
    ThreadTest w;
    w.show();

    return a.exec(); 
}

uji thread.h

#include <QWidget>
#include <QThread>
#include "worker.h"     

namespace Ui 
{
    class ThreadTest;
}

class ThreadTest : public QWidget
{
    Q_OBJECT

public:
    explicit ThreadTest(QWidget *parent = 0);
    ~ThreadTest();

signals:
    void startWorkSignal();
    void stopWorkSignal();


private slots:
    void on_startButton_clicked();
    void on_stopButton_clicked();

private:
    Ui::ThreadTest *ui;
    worker *myWorker;
    QThread *WorkerThread;
};

threadtest.cpp

#include "threadtest.h"
#include "ui_threadtest.h"

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

    myWorker = new worker;
    WorkerThread = new QThread;
    myWorker->moveToThread(WorkerThread);

    connect(this,
            SIGNAL(startWorkSignal()),
            myWorker,
            SLOT(StartWork())
            );

    connect(this,
            SIGNAL(stopWorkSignal()),
            myWorker,
            SLOT(StopWork())
            );

    //Debug
    this->dumpObjectInfo();
    myWorker->dumpObjectInfo(); 
}

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

void ThreadTest::on_startButton_clicked() 
{
    qDebug() << "startwork signal emmitted";
    emit startWorkSignal(); 
}

void ThreadTest::on_stopButton_clicked() 
{
    qDebug() << "stopwork signal emmitted";
    emit stopWorkSignal(); 
}

pekerja.h

#include <QObject>
#include <QDebug>

class worker : public QObject {
    Q_OBJECT 
public:
    explicit worker(QObject *parent = 0);
    ~worker();

signals:
    void SignalToObj_mainThreadGUI();
    //void running();
    //void stopped();

public slots:
    void StopWork();
    void StartWork();

private slots:
    void do_Work();

private:
    volatile bool running, stopped; 
};

pekerja.cpp

#include "worker.h"

worker::worker(QObject *parent) : QObject(parent), stopped(false),
running(false) 
{
    qDebug() << "running: " << running;
    qDebug() << "stopped: " << stopped; 

}


worker::~worker() {}

void worker::do_Work() 
{
    qDebug() << "inside do Work";
    emit SignalToObj_mainThreadGUI();

    if (!running || stopped) return;

    // actual work here
    /*
    for (int i = 0; i < 100; i++)
    {
        qDebug() << "count: " + i;
    }
    */
    QMetaObject::invokeMethod(this, "do_Work", Qt::QueuedConnection); 
}

void worker::StopWork() 
{
    qDebug() << "inside StopWork";
    stopped = true;
    running = false;

    //emit stopped(); 
}

void worker::StartWork() 
{
    qDebug() << "inside StartWork";
    stopped = false;
    running = true;

    //emit running();
    do_Work(); 
}

person Langleson    schedule 07.07.2015    source sumber


Jawaban (2)


Anda harus menulis

WorkerThread->start();

Atau Anda dapat menggunakan thread dari objek ThreadTest sebagai pengganti WorkerThread (dalam hal ini WorkerThread tidak diperlukan):

 myWorker->moveToThread(thread()); // this->thread
person Pavel Matrenin    schedule 08.07.2015

Slot tidak terpicu, karena Anda telah memindahkan myWork ke thread WorkerThread, namun tidak menjalankan perulangan peristiwa di thread tersebut. Di threadtest.cpp, tambahkan

WorkerThread .start();

setelah

myWorker = new worker;
WorkerThread = new QThread;
myWorker->moveToThread(WorkerThread);
person Yang Kui    schedule 08.07.2015