Qt - 使用按钮控制的线程的简单示例

时间:2015-07-07 23:55:58

标签: c++ qt qthread

我一直试图通过按钮激活的线程来实现这个简单的例子。它基于以下问题中的解决方案:

How to implement frequent start/stop of a thread (QThread)

上面的示例解决方案与我的代码之间的主要区别是:

  1. 我使用了QWidget而不是MainWindow
  2. 为清晰起见,我更改了信号名称
  3. 我的代码包含调试信息
  4. 我尝试消除工人创造的信号,因为没有做任何事情
  5. 看起来启动/停止信号没有触发相应的插槽,但我没有足够的经验来解决原因。

    此外,我不确定信号的目的:

      

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

2 个答案:

答案 0 :(得分:1)

不会触发插槽,因为您已将myWork移动到线程WorkerThread,但未在该线程中运行事件循环。在threadtest.cpp中,添加

WorkerThread .start();

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

答案 1 :(得分:1)

你应该写

WorkerThread->start();

或者您可以使用ThreadTest对象的线程而不是WorkerThread(在这种情况下,WorkerThread是不必要的):

 myWorker->moveToThread(thread()); // this->thread