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中QGroupBox控件的实现

《Qt中QGroupBox控件的实现》QGroupBox是Qt框架中一个非常有用的控件,它主要用于组织和管理一组相关的控件,本文主要介绍了Qt中QGroupBox控件的实现,具有一定的参考价值,感兴趣... 目录引言一、基本属性二、常用方法2.1 构造函数 2.2 设置标题2.3 设置复选框模式2.4 是否

QT进行CSV文件初始化与读写操作

《QT进行CSV文件初始化与读写操作》这篇文章主要为大家详细介绍了在QT环境中如何进行CSV文件的初始化、写入和读取操作,本文为大家整理了相关的操作的多种方法,希望对大家有所帮助... 目录前言一、CSV文件初始化二、CSV写入三、CSV读取四、QT 逐行读取csv文件五、Qt如何将数据保存成CSV文件前言

Qt中QUndoView控件的具体使用

《Qt中QUndoView控件的具体使用》QUndoView是Qt框架中用于可视化显示QUndoStack内容的控件,本文主要介绍了Qt中QUndoView控件的具体使用,具有一定的参考价值,感兴趣的... 目录引言一、QUndoView 的用途二、工作原理三、 如何与 QUnDOStack 配合使用四、自

Qt spdlog日志模块的使用详解

《Qtspdlog日志模块的使用详解》在Qt应用程序开发中,良好的日志系统至关重要,本文将介绍如何使用spdlog1.5.0创建满足以下要求的日志系统,感兴趣的朋友一起看看吧... 目录版本摘要例子logmanager.cpp文件main.cpp文件版本spdlog版本:1.5.0采用1.5.0版本主要

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

Java终止正在运行的线程的三种方法

《Java终止正在运行的线程的三种方法》停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作,停止一个线程可以用Thread.stop()方法,但最好不要用它,本文给大家介绍了... 目录前言1. 停止不了的线程2. 判断线程是否停止状态3. 能停止的线程–异常法4. 在沉睡中停止5

Qt 中 isHidden 和 isVisible 的区别与使用小结

《Qt中isHidden和isVisible的区别与使用小结》Qt中的isHidden()和isVisible()方法都用于查询组件显示或隐藏状态,然而,它们有很大的区别,了解它们对于正确操... 目录1. 基础概念2. 区别清见3. 实际案例4. 注意事项5. 总结1. 基础概念Qt 中的 isHidd

QT移植到RK3568开发板的方法步骤

《QT移植到RK3568开发板的方法步骤》本文主要介绍了QT移植到RK3568开发板的方法步骤,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录前言一、获取SDK1. 安装依赖2. 获取SDK资源包3. SDK工程目录介绍4. 获取补丁包二

Qt把文件夹从A移动到B的实现示例

《Qt把文件夹从A移动到B的实现示例》本文主要介绍了Qt把文件夹从A移动到B的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录如何移动一个文件? 如何移动文件夹(包含里面的全部内容):如何删除文件夹:QT 文件复制,移动(

Java捕获ThreadPoolExecutor内部线程异常的四种方法

《Java捕获ThreadPoolExecutor内部线程异常的四种方法》这篇文章主要为大家详细介绍了Java捕获ThreadPoolExecutor内部线程异常的四种方法,文中的示例代码讲解详细,感... 目录方案 1方案 2方案 3方案 4结论方案 1使用 execute + try-catch 记录