1. 程式人生 > 其它 >19. 執行緒的第二種方式

19. 執行緒的第二種方式

技術標籤:QT

mywidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"
#include <QDebug>


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

    //動態分配空間,不能指定父物件
    myT = new MyThread;

    //建立子執行緒
    thread = new QThread(this);

    //把自定義執行緒加入到子執行緒中
    myT->moveToThread(thread);

    connect(myT, &MyThread::mySignal, this, &MyWidget::dealSignal);

    qDebug() << "主執行緒號:" << QThread::currentThread();

    connect(this, &MyWidget::startThread, myT, &MyThread::myTimeout);


    connect(this, &MyWidget::destroyed, this, &MyWidget::dealClose);

    //執行緒處理函式內部,不允許操作圖形介面


    //connect()第五個引數的作用,連線方式:預設,佇列,直接
    //多執行緒時才有意義
    //預設的時候
    //如果是多執行緒,預設使用佇列
    //如果是單執行緒, 預設使用直接方式
    //佇列: 槽函式所在的執行緒和接收者一樣
    //直接:槽函式所線上程和傳送者一樣


}

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

void MyWidget::dealClose()
{
    on_buttonStop_clicked();
    delete myT;
}

void MyWidget::dealSignal()
{
    static int i = 0;
    i++;
    ui->lcdNumber->display(i);
}

void MyWidget::on_buttonStart_clicked()
{

    if(thread->isRunning() == true)
    {
        return;
    }

    //啟動執行緒,但是沒有啟動執行緒處理函式
    thread->start();
    myT->setFlag(false);

    //不能直接呼叫執行緒處理函式,
    //直接呼叫,導致,執行緒處理函式和主執行緒是在同一個執行緒
    //myT->myTimeout();

    //只能通過 signal - slot 方式呼叫
    emit startThread();


}

void MyWidget::on_buttonStop_clicked()
{
    if(thread->isRunning() == false)
    {
        return;
    }

    myT->setFlag(true);
    thread->quit();
    thread->wait();
}

mythread.cpp

#include "mythread.h"
#include <QThread>
#include <QDebug>
#include <QMessageBox>

MyThread::MyThread(QObject *parent) : QObject(parent)
{
    isStop = false;
}

void MyThread::myTimeout()
{
    while( !isStop )
    {

        QThread::sleep(1);
        emit mySignal();
        //QMessageBox::aboutQt(NULL);

         qDebug() << "子執行緒號:" << QThread::currentThread();

         if(isStop)
         {
             break;
         }
    }
}

void MyThread::setFlag(bool flag)
{
    isStop = flag;
}