QT实例——多线程+定时器

时间:2022-06-28 23:32:54
/*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()返回的句柄判断是哪个定时器被触发,进而做出不同的响应。