线程使用有两种方法:
一、继承QThread,实现它的run()函数,将需要执行的耗时代码放在run()里面运行
void myThread::run()
{
m_stop = false;
while (!m_stop)
{
/*耗时任务*/
...
}
}
- 此方法,如果要退出可使用
void myThread::stop()
{
m_stop = true;
quit();
wait();
}
- 使用时,调用start()函数,则相当于执行run()函数,在程任务执行完毕时,会发出 finished() 信号
/*子类化线程*/
mythread = new myThread();
connect(mythread,SIGNAL(finished()),this,SLOT(dealfinished()));
mythread->start();
二、使用moveToThread(),即子类化一个QObject实现需要执行的操作,再将派生类对象移到QThread中,并通过信号和槽触开始执行
/*QObject派生类,即耗时工作在这里实现*/
work = new Work;
/*通过信号和槽获取返回信息*/
connect(work,SIGNAL(resultReady(int)),this,SLOT(dealWorkresultReady(int)));
/*将派生类对象移动到QThread中*/
thread = new QThread(this);
connect(thread,SIGNAL(finished()),this,SLOT(dealfinished_2()));
work->moveToThread(thread);
/*通过信号链接派生类的槽函数,并通过信号触发*/
connect(thread,SIGNAL(started()),work,SLOT(start()));
thread->start();
三、实现案例及代码
法一 子类化QThread mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
class myThread : public QThread
{
Q_OBJECT
public:
explicit myThread(QObject *parent = NULL);
void stop();
protected:
virtual void run();
signals:
void resultReady(int value);
private:
bool m_stop;
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
myThread::myThread(QObject *parent) : QThread(parent)
{
}
void myThread::stop()
{
m_stop = true;
quit();
wait();
}
void myThread::run()
{
/*start会触发run,即需要执行的耗时工作加这里*/
m_stop = false;
int nValue = 0;
while (nValue < 100 && !m_stop)
{
emit resultReady(nValue);
/*耗时0.5秒*/
system("sleep 0.5");
++nValue;
/*发送信号,更新进度条*/
}
}
法二 子类化QObject work.h
#ifndef WORK_H
#define WORK_H
#include <QObject>
class Work : public QObject
{
Q_OBJECT
public:
explicit Work(QObject *parent = NULL);
void stop();
public slots:
void start();
signals:
void resultReady(int value);
private:
bool m_stop;
};
#endif // WORK_H
work.cpp
#include "work.h"
Work::Work(QObject *parent) : QObject(parent)
{
}
void Work::stop()
{
m_stop = true;
}
void Work::start()
{
m_stop = false;
int nValue = 0;
while (nValue < 100 && !m_stop )
{
emit resultReady(nValue);
/*耗时0.5秒*/
system("sleep 0.5");
++nValue;
}
}
效果图界面 widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDateTime>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
/*定时器,加载时间*/
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(dealTimeout()));
timer->start(1000);
ui->progressBar->setValue(0);
ui->progressBar->setMaximum(100);
ui->progressBar_2->setValue(0);
ui->progressBar_2->setMaximum(100);
ui->progressBar_3->setValue(0);
ui->progressBar_3->setMaximum(100);
/*子类化线程*/
mythread = new myThread(this);
connect(mythread,SIGNAL(resultReady(int)),this,SLOT(dealresultReady(int)));
connect(mythread,SIGNAL(finished()),this,SLOT(dealfinished()));
/*QObject派生类,即耗时工作在这里实现*/
work = new Work;
/*通过信号和槽获取返回信息*/
connect(work,SIGNAL(resultReady(int)),this,SLOT(dealWorkresultReady(int)));
/*将派生类对象移动到QThread中*/
thread = new QThread(this);
connect(thread,SIGNAL(finished()),this,SLOT(dealfinished_2()));
work->moveToThread(thread);
/*通过信号链接派生类的槽函数,并通过信号触发*/
connect(thread,SIGNAL(started()),work,SLOT(start()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::dealresultReady(int value)
{
ui->progressBar->setValue(value);
}
void Widget::dealWorkresultReady(int value)
{
ui->progressBar_3->setValue(value);
}
void Widget::on_pushButton_1_clicked()
{
if(!mythread->isRunning()){
ui->pushButton_1->setText("stop");
mythread->start();
}else{
ui->pushButton_1->setText("start_1");
mythread->stop();
}
}
void Widget::on_pushButton_2_clicked()
{
if(!thread->isRunning()){
ui->pushButton_2->setText("stop");
thread->start();
}else{
ui->pushButton_2->setText("start_2");
work->stop();
thread->quit();
thread->wait();
}
}
void Widget::on_pushButton_clicked()
{
ui->label_2->setText("<font style='color: red;'>完犊子,直接卡死! 点其他按钮么反应! 时间都没更新了!</font>");
update();
int cnt=0;
while(cnt < 100)
{
system("sleep 0.5");
ui->progressBar_2->setValue(cnt);
cnt++;
update();
}
}
void Widget::dealfinished()
{
qDebug()<< "start_1 over";
}
void Widget::dealfinished_2()
{
qDebug()<< "start_2 over";
}
void Widget::dealTimeout()
{
QDateTime dateTime = QDateTime::currentDateTime();
QString date = dateTime.toString("hh:mm:ss");
ui->label_3->setText("当前时间:"+date);
}