Qt - ตัวอย่างง่ายๆ โดยใช้เธรดที่ควบคุมโดยปุ่มกด

ฉันพยายามรับตัวอย่างง่ายๆ นี้โดยใช้เธรดที่เปิดใช้งานโดยปุ่มกดเพื่อทำงาน มันขึ้นอยู่กับวิธีแก้ปัญหาในคำถามด้านล่าง:

วิธีการเริ่ม/หยุดเธรดบ่อยครั้ง (QThread )

ความแตกต่างหลักระหว่างโซลูชันตัวอย่างด้านบนและโค้ดของฉันด้านล่างคือ:

  1. ฉันใช้ QWidget แทน MainWindow
  2. ฉันเปลี่ยนชื่อสัญญาณเพื่อความชัดเจน
  3. รหัสของฉันมีข้อมูลการดีบัก
  4. ฉันทดลองกำจัดสัญญาณที่คนงานสร้างขึ้นเนื่องจากไม่ได้ทำอะไรเลย

ดูเหมือนว่าสัญญาณเริ่ม/หยุดไม่กระตุ้นช่องที่สอดคล้องกัน แต่ฉันไม่มีประสบการณ์เพียงพอที่จะแก้ไขปัญหาว่าทำไม

นอกจากนี้ ฉันไม่แน่ใจในวัตถุประสงค์ของสัญญาณ:

SignalToObj_mainThreadGUI()

นั่นเป็นเพียงสิ่งที่สามารถใช้ได้และไม่ใช่?

ฉันพยายามทำให้โค้ดนี้ใช้งานได้มาระยะหนึ่งแล้ว ดังนั้นความช่วยเหลือใด ๆ จะได้รับการชื่นชมอย่างมาก

main.cpp

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

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

    return a.exec(); 
}

threadtest.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(); 
}

worker.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; 
};

worker.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 แหล่งที่มา


คำตอบ (2)


คุณควรเขียน

WorkerThread->start();

หรือคุณสามารถใช้เธรดของวัตถุ ThreadTest แทน WorkerThread (ในกรณีนี้ WorkerThread ไม่จำเป็น):

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

สล็อตไม่ถูกทริกเกอร์ เนื่องจากคุณได้ย้าย myWork ไปที่เธรด WorkerThread แต่ไม่ได้รันลูปเหตุการณ์ในเธรดนั้น ใน threadtest.cpp ให้เพิ่ม

WorkerThread .start();

หลังจาก

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