QT多线程实战_Qt多线程开发项目

文章目录

  • 多线程
  • 线程间通信
  • 终止多线程

文章目录

  • 多线程
  • 线程间通信
  • 终止多线程

多线程

QThread是Qt中最基础的线程类,每个实例都可以控制一个线程。其传统的调用方式是,新建一个继承QThread的类,然后将耗时任务写入run函数。而自QT4.4之后,则建议通过moveToThread()函数来调用多线程。

首先新建一个类,在项目中Ctrl+N,在弹出对话框中选择Files and Classes->C/C++->C++ Class,定义类的名称为ThTest,并选中QObject。

令该类继承QObject,将头文件中的ThTest改为

class ThTest : public QObject
{ 
   
    Q_OBJECT
public:
    ThTest();
    ~ThTest();
    void Func(void);
};

相应地,cpp文件的内容为

#include "thtest.h"
#include <QDebug>
#include <QThread>

ThTest::ThTest(){ 
   }
ThTest::~ThTest(){ 
   }

void ThTest::Func()
{ 
   
    int NowNum = 0;
    while(true){ 
   
        NowNum++;
        qDebug()<<NowNum<<QThread::currentThreadId();
    }
}

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

然后更改mainwindow的代码,在其头文件内容如下

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QThread>
#include <QObject>
#include <QDebug>
#include "thtest.h"
QT_BEGIN_NAMESPACE
namespace Ui { 
 class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{ 

Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
signals:
void ToThread(); // 信号
private slots:
void on_pbStart_clicked();
private:
Ui::MainWindow *ui;
QThread *qThTest;
ThTest *th1;
};
#endif

然后将cpp文件中的on_pbStart_clicked函数改为

void MainWindow::on_pbStart_clicked()
{ 

qThTest = new QThread;
th1 = new ThTest;
connect(this,&MainWindow::ToThread,th1,&ThTest::Func);
th1->moveToThread(qThTest);
qThTest->start();
emit ToThread();
}

其中,connect将ToThread函数和ThTest中的Func函数绑定在了一起。也就是说,当这边发射ToThread的信号的时候,Th1会执行Func这个函数。

所以,当线程启动后,通过emit发射ToThread信号,果然命令行中会持续输出数字了,同时窗口并不会死掉。

到了这一步,其实已经可以处理一些多线程任务了,但还不能把递增的NowNum显示到主窗口上,从而让lineEdit看上去有些鸡肋。为了实现在窗口上显示递增的数字,接下来需要做的就是线程间的通信。

线程间通信

得益于Qt的信号槽机制,多线程之间的通信并不复杂。乃至于,可以广义地认为emit ToThread()本身也是一个线程间通信的过程。

所以只需在on_pbStart_clicked中添加一条

connect(th1,SIGNAL(sendInt(int)),this,SLOT(getInt(int)));

意思就是th1发射一个sendInt(int),this接收一个getInt(int),这两个函数的名字无所谓,但一定不包含形参,而只有形参的数据类型。

接下来,在thtest.h中添加sendInt,

signals:
void sendInt(int);

并更改其Func函数

void ThTest::Func(){ 

int NowNum = 0;
while(true){ 

QThread::sleep(1);
emit sendInt(NowNum++);
}
}

最后,在mainwindow.h中添加

private slots:
void getInt(int);

以及cpp文件中的

void MainWindow::getInt(int num){ 

ui->lineEdit->setText(QString::number(num));
}

这样,在点击start之后,就可以看到lineEdit上数字的变化了。

 

终止多线程

最后,回到一开始的需求,是点击start开始,然后按钮变为stop,点击stop后再停止。

考虑到terminate并不安全,故而采用终结while的方式来退出死循环。方法是在ThTest中添加一个bool类型的成员running,即在头文件中添加

public:
bool running=true;

并更改源文件中的while循环

void ThTest::Func(){ 

int NowNum = 0;
while(running){ 

emit sendInt(NowNum++);
QThread::sleep(1);
}
}

最后修改on_pbStart_clicked

void MainWindow::on_pbStart_clicked()
{ 

bool flag = QString::compare(ui->pbStart->text(),"stop");
qDebug()<<ui->pbStart->text();
th1->running = flag;
ui->pbStart->setText(flag?"stop":"start");
if(flag){ 

th1->moveToThread(qThTest);
qThTest->start();
emit ToThread();
}
else
ui->lineEdit->setText("0");
}

并把th1等初始化过程移除去

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow)
{ 

ui->setupUi(this);
qThTest = new QThread;
th1 = new ThTest;
connect(th1,SIGNAL(sendInt(int)),this,SLOT(getInt(int)));
connect(this,&MainWindow::ToThread,th1,&ThTest::Func);
}

结果线程果然终止了

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个跨平台的C++应用程序开发框架,具有良好的可扩展性和易于使用的特点。而CSDN是一个国内知名的技术社区,提供了大量的编程教程和经验分享。 Qt项目实战CSDN可以是一个关于Qt开发的教程或者项目案例分享。在这个项目中,我会结合Qt的特点,通过撰写一系列的技术文章或者视频教程,详细介绍如何使用Qt进行应用程序的开发。 在这个项目中,我会从安装Qt开始,讲解Qt的基础知识,如界面设计、信号与槽机制、Qt对象模型等。然后,我会介绍Qt的高级特性,比如网络编程、数据库操作、多线程等。通过这些文章或者教程,读者可以系统地学习Qt的各个方面,从而快速掌握Qt开发技巧。 同时,为了更好地帮助读者理解和学习Qt,我会结合实际的项目案例,展示如何使用Qt进行实际应用的开发。具体案例可以涵盖不同的领域,比如一个简单的音乐播放器、一个图像处理应用、一个聊天程序等。通过这些案例,读者可以更好地理解Qt的实际应用场景,并且通过参考案例代码,快速上手Qt开发。 除了撰写技术文章或者制作视频教程,我还会积极参与到CSDN的技术社区中,回答读者的问题,与他们交流经验。这样可以进一步提升读者对于Qt开发的理解,并且根据读者的反馈,不断优化项目内容,使之更加符合读者的需求。 通过Qt项目实战CSDN,我希望能够帮助更多的开发者掌握Qt开发技巧,实现自己的应用想法。同时,也希望能够通过与读者的交流,不断提升自己的技术水平,共同促进技术的发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值