最近学习了一点点QThread,以下是一点点笔记:
问题: 如何通过QThread后台执行一些计算工作,而保持程序主界面的活动呢??
其中最简单的方法就是重定义QThread的虚函数run(),将要做的工作放进这个函数
那我想问,子类化QThread后的类的普通public函数呢??
以下workThread 类有一个public函数work();
1: 在主程序下调用work()
2: 在主程序调用workThread.start(),然后run()会被调用,run()里再调用work()
我们比较这两种情况的差异
首先是子类化QThread,实现自己的Thread
workthread.h
////
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>
class workThread : public QThread
{
Q_OBJECT
public:
explicit workThread(QObject *parent = 0);
void _work();
protected:
void run();
private:
double _A;
};
#endif // WORKTHREAD_H
///
workthread.cpp:
//
#include "workthread.h"
#include<QTime>
#include<QDebug>
workThread::workThread(QObject *parent) :
QThread(parent)
{
}
void workThread::run()
{
_work();
}
void workThread::_work() //这个函数执行11--12秒左右
{
qDebug()<<"start _setFileName "+QTime::currentTime().toString();
for(int i=1; i<=100000; i++)
for(int j=1; j<=100000; j++)
{
_A = i*j;
}
qDebug()<<"Finish _setFileName "+QTime::currentTime().toString();
}
///
然后到dialog:
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include"workthread.h"
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private slots:
void on_pushButton_clicked();
private:
Ui::Dialog *ui;
workThread _myworkThread;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include<QTime>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
_myworkThread.wait(); //Blocks the thread 释构时先阻塞这个线程
delete ui;
}
void Dialog::on_pushButton_clicked()
{
ui->label->setText("point 1 : "+QTime::currentTime().toString());
_myworkThread._work();
ui->label_2->setText("point 2 : "+QTime::currentTime().toString());
//这段代码的计时证明,QThread 的普通函数依然是由主线段执行的
_myworkThread.start();
ui->label_3->setText("point 3 : "+QTime::currentTime().toString());
//这段代码的计时证明,QThread 的start/run函数是由QThread的独立的线段执行的
//所以如果想简单后台独立线程执行代码的话,就简单重定义虚函数run()就可以了
}
最后就是main.cpp
#include <QtGui/QApplication>
#include "dialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
///程序运行时
//按下按钮后...一会儿后,窗口无法响应
最后这样的结果
1: 在主程序下调用work()
2: 在主程序调用workThread.start(),然后run()会被调用,run()里再调用work()
void Dialog::on_pushButton_clicked()
{
ui->label->setText("point 1 : "+QTime::currentTime().toString());
_myworkThread._work(); //情况1:
ui->label_2->setText("point 2 : "+QTime::currentTime().toString());
//这段代码的计时证明,QThread 的普通函数依然是由主线程执行的
_myworkThread.start(); //情况2:
ui->label_3->setText("point 3 : "+QTime::currentTime().toString());
//这段代码的计时证明,QThread 的start/run函数是由QThread的独立的线段执行的
//所以如果想简单后台独立线程执行代码的话,就简单重定义虚函数run()就可以了
}
A:从qDebug输出看出,情况1,情况2的运行时间都是11--12秒.....说明实际执行时间是一样的...
B:按下按钮后...一会儿后,窗口无法响应,此时,程序正在执行情况1,所以说明情况1中
子类化QThread后的类的普通public函数是由主线程执行的,直接导致主窗口无法响应
ui->label_2->setText("point 2 : "+QTime::currentTime().toString());
//这段代码的计时证明,QThread 的普通函数依然是由主线程执行的
_myworkThread.start(); //情况2:
ui->label_3->setText("point 3 : "+QTime::currentTime().toString());
的执行时间是0的,说明workThread.start()函数是由Thread的独立的线段执行的
结论:子类化 QThread 的普通函数依然是由主线程执行的,Thread 的start/run函数是由QThread的独立的线段执行的,所以如果想简单后台独立线程执行代码的话,就简单重定义虚函数run()就可以了