QThread的run函数与其它普通成员函数的区别

探讨如何通过QThread后台执行计算任务,同时保持主界面的交互活动,包括子类化QThread后的类的普通public函数在主线程与独立线程的执行差异,以及如何避免主窗口响应中断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近学习了一点点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:

QThread的run函数与其它普通成员函数的区别

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>

QThread的run函数与其它普通成员函数的区别

///程序运行时

<wbr></wbr>

QThread的run函数与其它普通成员函数的区别

//按下按钮后...一会儿后,窗口无法响应

<wbr></wbr>

QThread的run函数与其它普通成员函数的区别

最后这样的结果

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:QThread的run函数与其它普通成员函数的区别,这个说明这段代码

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()就可以了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值