QT實例——多線程+定時器

/*dialog.h*/
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QPushButton>
#include <QLCDNumber>
#include <QEvent>
#include <QThread>
#include <QProgressBar>

class MyThread : public QThread{
    Q_OBJECT
public:
    MyThread(){}
    ~MyThread(){}
    void run();
private:
};

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = 0);
    ~Dialog();
private:
    QPushButton * startBtn, *stopBtn;
    QLCDNumber * lCDNumber;
    QProgressBar * progressBar;
    int timerHandler;
    MyThread * myThread;
protected:
    void timerEvent(QTimerEvent *event);
private slots:
    void on_start();
    void on_stop();



};

#endif // DIALOG_H
/*dialog.cpp*/
#include "dialog.h"
#include <QGridLayout>
#include <QDebug>

static int val = 0;

void MyThread::run(){
    int index = 0;
    while(++index < 1000){
        ++val;
        QThread::msleep(15);
    }
}

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{
    val = 0;
    timerHandler = 0;
    QGridLayout * layout = new QGridLayout(this);
    lCDNumber = new QLCDNumber;
    lCDNumber->display(val);
    layout->addWidget(lCDNumber, 0, 0, 1, 0);


    progressBar = new QProgressBar;
    progressBar->setValue(0);
    layout->addWidget(progressBar, 1, 0, 1, 0);


    startBtn = new QPushButton("s&tart");
    connect(startBtn, SIGNAL(clicked()), this, SLOT(on_start()));
    startBtn->setStyleSheet("width:30;height:20");

    stopBtn = new QPushButton(tr("s&top"));
    connect(stopBtn, SIGNAL(clicked()), this, SLOT(on_stop()));
    stopBtn->setStyleSheet("width:30;height:20");
    layout->addWidget(startBtn, 2, 0);
    layout->addWidget(stopBtn, 2, 1);
    this->setFixedSize(220, 120);

}

Dialog::~Dialog()
{

}

void Dialog::timerEvent(QTimerEvent *event){
    qDebug() << "Timer ID:" << event->timerId()\
             <<"------"<<timerHandler\
               <<"------"<<val;

    lCDNumber->display(val);
    progressBar->setValue(val*100/999);
}

void Dialog::on_start(){
    //new thread
    myThread = new MyThread;
    myThread->start();
    if(timerHandler == 0){
        timerHandler = this->startTimer(1);
    }

}

void Dialog::on_stop(){
    myThread->terminate();
    this->killTimer(timerHandler);
    timerHandler = 0;
    lCDNumber->display(val);
}

主線程不可以被阻塞,否則UI無法刷新,程序會顯示無法響應。這個例子中,子線程負責處理業務邏輯(修改val的值),定時器負責刷新lCDNumber個progressBar的值。顯然主線程被阻塞。

QT提供了2種定時器。這裏用的是比較簡單的一種。在此如果啓動了多個定時器,那麼這些定時器將共用一個時間回調函數。當然可以根據event->timerId()返回的句柄判斷是哪個定時器被觸發,進而做出不同的響應。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章