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