QT线程之“旁门左道”之一

2024-02-24 11:30
文章标签 线程 qt 旁门左道

本文主要是介绍QT线程之“旁门左道”之一,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在QT中有自己的线程处理机制,大家都知道在处理大量的数据的时候,一般会单独的开启一个线程来处理,这样做的好处有两个方面:一个是提高数据处理运行的速度;另外一个就是在线程中处理数据,不会影响主线程的运行。如果在主线程中来加载大量的数据,主线程就会“卡住”,出现程序假死的情况,非常影响用户的使用体验。

在线程中运行接口

QThread这个类是QT提供的单独来运行线程的类,只要子类继承并且实现run这个方法即可。

virtual void run();

然后调用start就可以启动线程来运行run这个方法。关于线程的同步请大家看我之前写过关于线程同步的文章QT多线程同步。
大家都知道的,关于工作线程和主线程进行通信也是通过信号槽来实现的,具体请看我另一篇文章,QT信号槽的在不同线程或者在同一线程下的连接方式
在线程中进行加载大量的数据,但是经常会出现这样的场景,比如说有一个类,这个类除了实现数据加载功能之外还要实现数据在表格中展示、点击表格的后的触发事件等其他的功能,这些功能并不是全部在线程中完成,特别是和界面操作相关的功能,更不能在工作线程中来实现, 只能在主线程中来实现。也就是说一个类的功能有一部分是在线程中实现而另一部分则不需要在工作线程中来完成。那么怎么办呢?

最好的办法就是,把需要在线程中完成的工作单独提出类作为一个父类,子类继承这个父类除了实现这个接口外还能扩展其他的功能,子类对象同时无论是工作线程中还是主线程都共有这个类对象中成员变量。提出的父类咱们可以称之为“接口”这就是面向对象编程中的面向接口编程(这里提到的接口并不是指的是java语言中的接口,而是和java语言中接口具有相同功能的父类而已)。

1.定义接口

#pragma once//数据加载接口class ILoadData {
public:ILoadData();~ILoadData();virtual void loadData() = 0;
};
#include "ILoadData.h"ILoadData::ILoadData() {
}ILoadData::~ILoadData() {
}

2.定义线程类,并且可以运行接口

#pragma once
#include "ILoadData.h"#include <QThread>class QtThreadLoad : public QThread {Q_OBJECTpublic:QtThreadLoad(ILoadData* load, QObject *parent);~QtThreadLoad();void run()override;
private:ILoadData* _loadData = nullptr;};
#include "QtThreadLoad.h"QtThreadLoad::QtThreadLoad(ILoadData* load, QObject *parent): QThread(parent) {_loadData = load;
}QtThreadLoad::~QtThreadLoad() {
}void QtThreadLoad::run() {if (_loadData != nullptr){_loadData->loadData();}
}

3.定义场景

先画一个界面:
在这里插入图片描述

#pragma once#include <QWidget>
#include "ui_QtGuiTable.h"
#include "ILoadData.h"
#include <vector>
#include "QtThreadLoad.h"class QtGuiTable : public QWidget,public ILoadData {Q_OBJECTpublic:QtGuiTable(QWidget *parent = Q_NULLPTR);~QtGuiTable();void initTable();virtual void loadData()override;
private slots:void slotUpdateName();void slotBtnLoad();
signals:void sigUpdate();
private:Ui::QtGuiTable ui;QtThreadLoad* threadLoad = nullptr;std::vector <QString> _nameList;//名称列表
};
#include "QtGuiTable.h"
#include <QTableWidgetItem>QtGuiTable::QtGuiTable(QWidget *parent): QWidget(parent) {ui.setupUi(this);initTable();connect(this, SIGNAL(sigUpdate()), this, SLOT(slotUpdateName()));connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(slotBtnLoad()));threadLoad = new QtThreadLoad(this, this);
}QtGuiTable::~QtGuiTable() {
}void QtGuiTable::initTable() {ui.tableWidget->setColumnCount(1);ui.tableWidget->setRowCount(100);
}
void QtGuiTable::loadData() {QString name;for (int i = 0; i < 100; i++) {name = QStringLiteral("张") + QString::number(i);_nameList.push_back(name);}emit sigUpdate();
}void QtGuiTable::slotUpdateName() {for (int i = 0; i < 100; i++) {ui.tableWidget->setItem(i, 0, new QTableWidgetItem(_nameList.at(i)));}
}void QtGuiTable::slotBtnLoad() {threadLoad->start();
}

以上就完成了面向接口编程!

下面分析一下程序运行的过程,看是顺序图:
在这里插入图片描述
现在大家看到这个过程了,其实线程运行过程中,只调用了对象中的通过继承来的接口,然后通过信号槽来实现界面的刷新。

Qt 线程池的使用以及和主线程的消息同步

这篇关于QT线程之“旁门左道”之一的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/741952

相关文章

QT Creator配置Kit的实现示例

《QTCreator配置Kit的实现示例》本文主要介绍了使用Qt5.12.12与VS2022时,因MSVC编译器版本不匹配及WindowsSDK缺失导致配置错误的问题解决,感兴趣的可以了解一下... 目录0、背景:qt5.12.12+vs2022一、症状:二、原因:(可以跳过,直奔后面的解决方法)三、解决方

Java中如何正确的停掉线程

《Java中如何正确的停掉线程》Java通过interrupt()通知线程停止而非强制,确保线程自主处理中断,避免数据损坏,线程池的shutdown()等待任务完成,shutdownNow()强制中断... 目录为什么不强制停止为什么 Java 不提供强制停止线程的能力呢?如何用interrupt停止线程s

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消

Qt中实现多线程导出数据功能的四种方式小结

《Qt中实现多线程导出数据功能的四种方式小结》在以往的项目开发中,在很多地方用到了多线程,本文将记录下在Qt开发中用到的多线程技术实现方法,以导出指定范围的数字到txt文件为例,展示多线程不同的实现方... 目录前言导出文件的示例工具类QThreadQObject的moveToThread方法实现多线程QC

SpringBoot实现虚拟线程的方案

《SpringBoot实现虚拟线程的方案》Java19引入虚拟线程,本文就来介绍一下SpringBoot实现虚拟线程的方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录什么是虚拟线程虚拟线程和普通线程的区别SpringBoot使用虚拟线程配置@Async性能对比H

在Java中实现线程之间的数据共享的几种方式总结

《在Java中实现线程之间的数据共享的几种方式总结》在Java中实现线程间数据共享是并发编程的核心需求,但需要谨慎处理同步问题以避免竞态条件,本文通过代码示例给大家介绍了几种主要实现方式及其最佳实践,... 目录1. 共享变量与同步机制2. 轻量级通信机制3. 线程安全容器4. 线程局部变量(ThreadL

Linux线程同步/互斥过程详解

《Linux线程同步/互斥过程详解》文章讲解多线程并发访问导致竞态条件,需通过互斥锁、原子操作和条件变量实现线程安全与同步,分析死锁条件及避免方法,并介绍RAII封装技术提升资源管理效率... 目录01. 资源共享问题1.1 多线程并发访问1.2 临界区与临界资源1.3 锁的引入02. 多线程案例2.1 为

Java中的xxl-job调度器线程池工作机制

《Java中的xxl-job调度器线程池工作机制》xxl-job通过快慢线程池分离短时与长时任务,动态降级超时任务至慢池,结合异步触发和资源隔离机制,提升高频调度的性能与稳定性,支撑高并发场景下的可靠... 目录⚙️ 一、调度器线程池的核心设计 二、线程池的工作流程 三、线程池配置参数与优化 四、总结:线程

WinForm跨线程访问UI及UI卡死的解决方案

《WinForm跨线程访问UI及UI卡死的解决方案》在WinForm开发过程中,跨线程访问UI控件和界面卡死是常见的技术难题,由于Windows窗体应用程序的UI控件默认只能在主线程(UI线程)上操作... 目录前言正文案例1:直接线程操作(无UI访问)案例2:BeginInvoke访问UI(错误用法)案例

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.