QT多线程实战

article/2025/10/27 16:17:19

文章目录

    • 需求的提出
    • 多线程
    • 线程间通信
    • 终止多线程

本文源码: QT多线程实战

需求的提出

窗口本身就是一个死循环,在这样一个死循环中执行任何耗时的操作,都会导致程序崩溃。所以多线程对于窗口编程而言是必要的。

例如,在窗口中拖入一个pushButtonlineEdit,将pushButton的名字改为pbStart,然后为其绑定一个函数,函数中创建一个死循环,并让死循环中的内容实时输出到lineEdit

接下来设计一个逻辑,当点击pbStart之后,开始执行死循环,同时按钮内容变为Stop;当按钮内容为Stop时,点击按钮,停止执行死循环。

所以,需要设计一个用于控制循环是否继续执行的成员变量,在MainWindow的头文件中添加私有成员bool flag。在cpp文件中添加flag = true

然后转到设计界面 ,右键pbStart按钮->转到槽->clicked()。从而MainWindow中添加了一个名为on_pbStart_clicked的函数,填充其内容为

void MainWindow::on_pbStart_clicked()
{int i= 0;bool flag = QString::compare(ui->pbStart->text(),"start");if(flag)ui->pbStart->setText("stop");while(flag){i++;ui->lineEdit->setText(QString::number(i));}
}

结果运行之后,果然陷入了死循环,程序也无法响应了,最过分的是lineEdit并没有变化,这个时候就要考虑多线程。

在这里插入图片描述

多线程

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();}
}

然后更改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_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic: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();
}

其中,connectToThread函数和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();}elseui->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);
}

结果线程果然终止了

在这里插入图片描述


http://chatgpt.dhexx.cn/article/cJXM9rBT.shtml

相关文章

Qt多线程之死锁

目录 一、造成死锁的原因 现象分析 二、死锁的概念和发生条件 三、死锁的避免 四、避免死锁的示例代码 一、造成死锁的原因 一般性原则&#xff0c;每个临界资源都需要一个线程锁来进行保护&#xff0c;假设有多个线程锁该怎么设计程序呢&#xff1f;先来看以下的一个示例…

QT多线程网络通信

QT多线程网络通信 使用QT提供的类进行基于TCP的套接字通信需要用到两个类&#xff1a; 1、QTcpServer 服务器类&#xff0c;用于监听客户端连接以及和客户端建立连接 2、QTcpSocket 通信的套接字类&#xff0c;客户端、服务器端都需要使用 ​ 这两个套接字通信类都属于网络…

QT 多线程应用

QT多线程的实现有两种方法&#xff0c;一种是继承QThread的多线程使用方法&#xff0c;另外一种是使用QObject实现多线的方法。传统的方式是继承QTread&#xff0c;但是这种方式比较的容易出错&#xff0c;QT官方推荐使用的是第二种方式。这里介绍这两种方式的最简单的一种创建…

Qt 多线程(QThread)

Qt 多线程&#xff08;QThread&#xff09; 一.理解QThread 关于QThread&#xff0c;参考qt助手中的解析 Detailed Description A QThread object manages one thread of control within the program. QThreads begin executing in run(). By default, run() starts the eve…

QT 多线程的实现方法以及GUI线程与其他线程间的通信

GUI线程 Qt应用程序exec后就会生成一个线程&#xff0c;这个线程就是主线程&#xff0c;在GUI程序中也称为GUI线程。主线程也是唯一允许创建QApplication或QCoreAppliation对象&#xff0c;比并且可以对创建的对象调用exec()的线程&#xff0c;从而进入事件循环。 在只有主线…

QT多线程接收串口数据

** QT多线程接收串口数据 ** 1.前言 QT多线程的使用&#xff0c;和绝大数人一样&#xff0c;犯了错误&#xff08;请查阅Qt开发人员( Bradley T. Hughes)Blog中的文章 you are-doing-it-wrong介绍&#xff09;。为了解决问题&#xff0c;网上查阅学习了几十篇文章&#xff0c…

Qt多线程互斥

目录 一、多线程与临界资源的依赖 现象分析 二、互斥和解决方法 三、QMutex的主要成员函数和使用 四、示例代码 五、小结 一、多线程与临界资源的依赖 除了上一节所说的&#xff0c;多线程在代码执行的时序上会有依赖&#xff0c;那么其他地方是否还有所依赖呢&#xff…

QT 多线程创建方法及应用实例

QT 多线程创建方法及应用实例 方法一&#xff1a; &#xff08;1&#xff09;创建一个QT应用 &#xff08;2&#xff09;创建线程类&#xff0c;继承QThread simplethreadone.h #ifndef SIMPLETHREADONE_H #define SIMPLETHREADONE_H #include <QThread>class SimpleThr…

Qt 多线程专栏

主线程就是进程&#xff0c;进程代表4个G的资源空间&#xff0c;主线程退出就意味着进程退出&#xff0c;在Qt中&#xff0c;主线程不能是子线程的父对象&#xff0c;因此必须在线程的析构函数中去delete线程对象。 只要定时器启动&#xff0c;自动触发timeout()信号 类A继承了…

Qt多线程编程

由于疫情原因被封控在家&#xff0c;相信大家也有跟我类似的情况&#xff0c;在学习知识提升和充实自己&#xff0c;下面我将这几天在学习的Qt多线程编程做个简单的总结&#xff0c;随此笔记的还有几个简单的例子&#xff0c;以便后续开发过程中回忆和参考。 Qt的多线程开发&am…

Qt多线程

Qt多线程有两种方法&#xff1a; 1、定义一个QThread的派生类&#xff0c;重写run函数&#xff0c;run函数中的程序就是新线程中要执行的内容。在主线程中实例化该类&#xff0c;调用start函数&#xff0c;就可以实现多线程。 2、定义一个QObject的派生类&#xff0c;把要在新线…

Qt创建多线程的两种方法

来源&#xff1a;https://github.com/czyt1988/czyBlog/tree/master/tech/QtThread 1.摘要 Qt有两种多线程的方法&#xff0c;其中一种是继承QThread的run函数&#xff0c;另外一种是把一个继承于QObject的类转移到一个Thread里。 Qt4.8之前都是使用继承QThread的run这种方法…

Qt----多线程

文章目录 多线程一、继承QThread的线程1. 应用实例2. 程序运行效果 二、继承QObject的线程1. 应用实例2. 程序运行效果 多线程 我们写的一个应用程序&#xff0c;应用程序跑起来后一般情况下只有一个线程&#xff0c;但是可能也有特殊情况。比如我们前面章节写的例程都跑起来后…

Qt5教程(九):Qt多线程

目录&#xff1a; 一、创建工程 二、QThread 源码一览 三、QThread相关方法介绍 四、创建线程 一、创建工程 先创建一个工程吧, 具体步骤前面讲过很多次了&#xff0c; 就不再细说了。 然后在Header文件夹下创建添加一个头文件, 右键Headers -> Add New... -> C -&g…

Qt 多线程的几种实现方式

Qt多线程的实现方式有&#xff1a; 1. 继承QThread类&#xff0c;重写run()方法 2. 使用moveToThread将一个继承QObject的子类移至线程&#xff0c;内部槽函数均在线程中执行 3. 使用QThreadPool,搭配QRunnable&#xff08;线程池&#xff09; 4. 使用QtConcurrent&#xf…

QT中的多线程

目录 1、QThread介绍 1.2、继承Qthread类 1.2.1、得到线程id 1.2.2、让线程一直执行 1.2.3、线程退出 1.2.4、​​​​​​​connect的第五个参数 1.2.5、线程锁 QMutex ​​​​​​​ 1、QThread介绍 QThread类提供了一个与平台无关的管理线程的方法。一个QThread对…

faild to create process解决办法

win7下运行pip时报faild to create process的解决办法&#xff1a; 1.找到python.exe文件&#xff0c;复制其文件路径。如下图&#xff0c;python.exe路径为D:\interpreter\python.exe。 2.找到pip-script.py文件&#xff0c;打开。将步骤1中复制的路径粘贴在第一行&#xff0…

CreateProcess error=2, 系统找不到指定的文件 解决方法

CreateProcess error2, 系统找不到指定的文件 解决方法 一般这是由于ndk缺少文件引起的 解决方法1&#xff1a; 在项目根目录下的local.properties文件中加cmd后缀 方法二下载16b的版本替换原来的ndk-bundle目录&#xff0c;默认在C:\Users\用户名\AppData\Local\Android\S…

SQL SERVER 2008 执行xp_cmdshell的过程中出错,调用createprocess失败,错误代码 5 解决方案

1、进入 控制面板----管理工具------本地安全策略 点击 本地策略--------安全选项 把“网络安全:LAN管理器身份验证级别”双击打开&#xff0c;选择“发送 LM 和 NTLM 响应”&#xff08;原来是“没有定义”&#xff09;。确认后&#xff0c;重新启动服务器&#xff0c;该问题…

runnerw.exe: CreateProcess failed with error 5:

在idea配置Git时遇到这个问题&#xff1a; 后来发现是我路径设置错了&#xff1a; 解决方案 修改设置里的路径即可&#xff08;Setings-Version Control-Git&#xff09;