Qt

2023-11-11

参考博客:QThread必须要了解的几个函数
https://blog.csdn.net/t46414704152abc/article/details/52155777
设计思路:读文件生成sql语句写入内存为一个线程,返回sql语句给主线程;主线程再调用写数据库操作线程。
其中包括:文件的读取;qt多线程;多线程访问数据库写入数据。
使用线程池读取大数据文件,测试通过。
测试使用的三个文件每个文件有32万多条数据,总计94万条数据,全部写入数据库预计需要三分钟时间。
整体结构:
在这里插入图片描述

ThreadPractice.h

// 使用线程池读取大数据文件,测试通过。
// 测试使用的三个文件每个文件有32万多条数据,总计94万条数据,全部写入数据库预计需要三分钟时间。
#pragma once
#pragma execution_character_set("utf-8")

#include <QWidget>
#include <QtCharts/qchartglobal.h>
#include <qthreadpool.h>
#include <qthread.h>
#include <qrunnable.h>
#include <queue>
#include <qmutex.h>
#include <QtSql/qtsqlglobal.h>
#include <qapplication.h>

// 保存数据库路径
static QString save_db_path;

// 读取文件线程 注册线程中处理函数,线程结束给主线程返回信号同时启动写数据库线程
class FileRunnable
	: public QObject
	, public QRunnable
{
	Q_OBJECT

public:
	explicit FileRunnable(QObject * parent = nullptr) {}
	~FileRunnable() {}

	void SetFunction(QStringList(FileRunnable::*_pf)(QString, QString)) {
		FileRunnable::pf = _pf;
	}

protected:
	void run() {
		QStringList sql_list = ThreadReadRangeFile(path_, table_name_);
		emit SendRunableSignal(sql_list);
		return;
	}

signals:
	void SendRunableSignal(QStringList);

public:
	QStringList ThreadReadRangeFile(QString, QString);
	QStringList(FileRunnable::*pf)(QString _path, QString _table_name);
	QString path_, table_name_;
};

// 数据库文件线程 注册线程中处理函数,线程结束给主线程返回信号
class DBRunnable
	: public QObject
	, public QRunnable
{
	Q_OBJECT

public:
	explicit DBRunnable(QObject* parent = nullptr){}
	~DBRunnable(){}

	void SetFuntion(bool(DBRunnable::*_pf)(QStringList)) {
		DBRunnable::pf = _pf;
	}

protected:
	void run() {
		bool flag = THreadWriteRangeTable(sql_list);
		emit SendRunableSignal(flag);
		return;
	}
signals:
	void SendRunableSignal(bool);

public:
	// 写入Range文件到数据库
	bool THreadWriteRangeTable(QStringList);

public:
	bool(DBRunnable::*pf)(QStringList);
	QStringList sql_list;
	QString uid;
};

class ThreadPractice 
	: public QWidget
{
	Q_OBJECT

public:
	ThreadPractice(QWidget *parent = nullptr);
	~ThreadPractice();

private:
	void Init();

	// 将.range文件转为db文件
	void FileRangeConversion(QString _path, QString _table_name);
	// 将.rcs文件转为db文件
	void FileRcseConversion(QString _path, QString _table_name);
	// 将.img文件转为db文件
	void FileImgConversion(QString _path, QString _table_name);

private slots:
	// 读取文件返回数据库语句
	void ThreadReadRangeFileSlot(QStringList);
	// 写入Range文件到数据库
	void ThreadWriteRangeTableSlot(bool);

private:
	// 线程池对象
	QThreadPool *thread_pool_;

};

ThreadPractice.cpp

#include "ThreadPractice.h"
#include <qgridlayout.h>
#include <qmessagebox.h>
#include <qsqldatabase.h>
#include <qsqlquery.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qsqlerror.h>
#include <qdebug.h>
#include <qdir.h>
#include <quuid.h>

QMutex mutex;

ThreadPractice::ThreadPractice(QWidget *parent)
	: QWidget(parent)
{
	Init();
}

ThreadPractice::~ThreadPractice()
{
}

void ThreadPractice::Init()
{
	thread_pool_ = new QThreadPool();
	thread_pool_->setMaxThreadCount(20);	// 线程池最多20个线程

	QFileInfoList InfoList = QDir(QApplication::applicationDirPath() + "/../../ThreadPractice/data/").entryInfoList();	// 获取当前目录下所有文件
	foreach (QFileInfo fileInfo, InfoList)
	{
		if (!fileInfo.isFile())	// 不是文件继续,只用于加速
			continue;
		if (fileInfo.suffix() == "range") {
			FileRangeConversion(fileInfo.filePath(), fileInfo.fileName());
		}
		if (fileInfo.suffix() == "rcs") {
			FileRcseConversion(fileInfo.filePath(), fileInfo.fileName());
		}
		if (fileInfo.suffix() == "img") {
			FileImgConversion(fileInfo.filePath(), fileInfo.fileName());
		}
	}
}

void ThreadPractice::FileRangeConversion(QString _path, QString _table_name)
{
	// 创建读取文件线程
	FileRunnable *runnable = new FileRunnable();
	runnable->path_ = _path;
	runnable->table_name_ = _table_name;
	connect(runnable, &FileRunnable::SendRunableSignal, this, &ThreadPractice::ThreadReadRangeFileSlot);
	runnable->SetFunction(&FileRunnable::ThreadReadRangeFile);
	runnable->setAutoDelete(true);
	thread_pool_->start(runnable);
}

void ThreadPractice::FileRcseConversion(QString _path, QString _table_name)
{
}

void ThreadPractice::FileImgConversion(QString _path, QString _table_name)
{
}

bool DBRunnable::THreadWriteRangeTable(QStringList _sql_list) {
	uid = QUuid::createUuid().toString();
	{
		// 将range转为数据库的表保存
		QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", uid);
		db.setDatabaseName(save_db_path);
		if (!db.open()) {
			QMessageBox::information(0, "unable", "can not open database", QMessageBox::Cancel);
			return false;
		}
		QSqlQuery query(db);	// 默认打开
		// 这个while循环为了解决当有多个文件时会产生多个线程连接数据库,此时创建表格会失败,因此等待成功后在进行后续操作。
		// 此处有个疑问:为什么不能多线程同时连接数据库?
		// 连接数据库创建表格失败,说被锁住了,但是我并没有上锁。
		// 2023/2/1 今天看到sqlite数据库仅支持单用户读写操作 
		while (1) {
			if (!query.exec(_sql_list[0])) {// 0为创建表格
				qDebug() << query.lastError() << "right";
				QThread::msleep(1);		// 如果操作失败则等待(不确定是否是query连接数据库时自动上锁)
				continue;
			}
			break;
		}
		db.transaction();
		for (int i = 1; i < _sql_list.size(); ++i) {
			if (!query.exec(_sql_list[i]))
				qDebug() << query.lastError() << "error";
		}
		db.commit();
		query.clear();
		db.close();
	}
	QSqlDatabase::removeDatabase(uid);
	return true;
}

void ThreadPractice::ThreadWriteRangeTableSlot(bool _flag) {
	if (_flag) {
		qDebug() << "文件转换完成!";
	}
	else {
		qDebug() << "文件转换失败!";
	}
}

// 读去range文件
QStringList FileRunnable::ThreadReadRangeFile(QString _path, QString _table_name) {
	QString save_path = QApplication::applicationDirPath() + "/../../ThreadPractice/data/";
	QString table_name_ = _table_name.mid(1, 5);	// 所有range文件存在一个db文件不同表格里,取文件名第20位开始10个字节的字符作为表名

	save_db_path = save_path + "range.db";

	// 打开文件
	QFile file(_path);
	if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
		qDebug() << "open filed!";

	QStringList sql_list;
	sql_list.clear();
	// 创建表
	QString create_str = QString("create table [%1] ([first] double,[second] double,[third] double,[fourth] double);").arg(table_name_);
	sql_list << create_str;
	// 重复表将之前数据删除
	//QString delete_str = QString("delete from %1;").arg(table_name_);
	//sql_list << delete_str;
	QTextStream in(&file);		// QTextStream读取数据
	in.readLine();
	while (!in.atEnd()) {
		QString fileLine = in.readLine();	// 从第二行读取至下一行
		QStringList list;		// 用于存储文件每行信息
		list.clear();
		list << fileLine.split(" ", QString::SkipEmptyParts);
		// 添加数据
		QString insert_str = QString("insert into [%1] ([first],[second],[third],[fourth]) values ('%2','%3','%4','%5')")
			.arg(table_name_).arg(list.at(0).toDouble()).arg(list.at(1).toDouble()).arg(list.at(1).toDouble()).arg(list.at(3).toDouble());
		sql_list << insert_str;
	}
	return sql_list;
}

// 读完后发送信号并启动写数据库线程
void ThreadPractice::ThreadReadRangeFileSlot(QStringList _sql_list) {
	// 执行sql语句写入数据库创建线程
	DBRunnable * runnable = new DBRunnable();
	QObject::connect(runnable, &DBRunnable::SendRunableSignal, this, &ThreadPractice::ThreadWriteRangeTableSlot);
	runnable->sql_list = _sql_list;
	runnable->SetFuntion(&DBRunnable::THreadWriteRangeTable);
	runnable->setAutoDelete(true);
	// 启动线程之前启动该数据库连接
	thread_pool_->start(runnable);
}

main.cpp

#include <QtCore/QCoreApplication>
#include "ThreadPractice.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

	ThreadPractice w;

    return a.exec();
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt 的相关文章

  • 使用 PyQt 和 matplotlib 在可滚动小部件中显示多个绘图

    由于我没有得到答案this https stackoverflow com questions 12179893 creating a scrollable multiplot with pythons pylab我尝试用 PyQt 解决这
  • Qt中正确的线程方式

    我的图像加载非常耗时 图像很大 并且在加载时也完成了一些操作 我不想阻止应用程序 GUI 我的想法是在另一个线程中加载图像 发出图像已加载的信号 然后用该图像重绘视图 我的做法 void Window loadImage ImageLoad
  • 将 UTC 格式的 QDateTime 转换为本地系统时间

    我从这样的字符串构造 QDateTime QDateTime date QDateTime fromString 2010 10 25T10 28 58 570Z yyyy MM ddTHH mm ss zzzZ 我知道date是 UTC
  • QWidget::showMinimized() 不起作用

    在 Ubuntu 13 04 上 如果使用QWidget showMinimized 为了最小化窗口 我发现通过单击系统任务栏上的应用程序图标恢复它后 调用QWidget showMinimized 无法工作 connect minimum
  • 扩展 TabViewStyle styleData

    我目前正在尝试找到一种更好的方法来执行此操作 将图标添加到选项卡 现在 我正在放弃 styleData title 以包含图标源 但如果能够扩展 styleData 就更好了 这样我就可以包含其他自定义属性 这是我当前的黑客 Tab tit
  • QWinTaskbarProgress 不会显示

    我使用的是windows7和Qt5 3 0 我在 MainWindow 的构造函数中添加了以下内容 但任务栏上没有显示任何内容 我错过了什么 QWinTaskbarProgress pTaskbarProgress new QWinTask
  • Qt 图表和数据可视化小部件

    我已经安装了 Qt 5 7 来尝试 Qt 图表和 Qt 数据可视化 但我在 Qt Designer 和 Qt Creator 中都找不到新的小部件 有什么建议我应该做什么才能让新的小部件出现在设计器中 我今天遇到了完全相同的问题 默认情况下
  • Qt 创建者 4.8.4。 Windows 7 - 64 位安装

    我在 QT 方面遇到了一些困难 我需要在学校使用它来完成一些 GUI 应用程序 我最近完成了以下步骤 1 mingw get inst 20120426 exefrom 来源锻造 http sourceforge net projects
  • 如何将flex和bison与Qt项目集成?

    我正在 git 源代码控制下使用 Qt4 制作 GUI 程序 Github页面 https github com vinayak garg dic sim 项目的一小部分需要扫描和解析 所以我想在项目中使用flex和bison 我能想到3种
  • 从 Qt 更改屏幕分辨率?

    我想更改屏幕分辨率 然后使用一个 ActiveX 控件 Flash 播放器 进入全屏 显然 仅适用于 Windows 的解决方案就可以了 有 Qt api 吗 还是我需要深入研究 winapi 如果是这样 我该在哪里查找 关键字 谢谢您的帮
  • QFileDialog 作为 TableView 的编辑器:如何获取结果?

    我正在使用一个QFileDialog作为某些专栏的编辑QTableView 这基本上有效 对一些焦点问题取模 请参阅here https stackoverflow com questions 22854242 qfiledialog as
  • 在 QtCreator 中调试时如何查看 qDebug 消息

    我正在从 Eclipse CDT 带有 Qt 集成插件 过渡到 QtCreator 2 0 但仍有一件事困扰着我 QtCreator 当我在 QtCreator 中调试时 我在Application output tab直到我停止正在调试的
  • 当给定 100k 项时,QListView 需要很长时间才能更新

    我在读取文件时遇到问题 具体是我想制作一本小字典 在我需要阅读的文件中有这样的内容 a Ph P6 a snsr CA a b c fb Dj a b c book i BS A except B gate oOPa y a font kQ
  • 在 QML 中控制纹理 3D 对象的不透明度

    我对 QML 中的 Qt 3D 有点陌生 我正在尝试控制 Qt 3D 的不透明度textured3D 对象 我正在使用简单qml3d https github com tripolskypetr simpleqml3d测试项目来做到这一点
  • Qt 码头调整大小事件

    有没有办法在 Qt 中捕捉码头的调整大小事件 我需要能够检测到扩展坞何时调整大小 而不仅仅是其位置或 功能 发生变化时 看起来 QDockWidget 没有 调整大小 信号 如果您不希望子类化以仅获得调整大小事件控件 您可以安装事件过滤器
  • 在 Windows 上静默安装 Qt55 Enterprise

    编辑 在 Qt 支持的帮助下 我已经解决了如何自动化 Qt 企业安装程序的这两个部分 下面是脚本调用 我正在尝试在 Windows 8 1 和 Windows 10 上静默安装 Qt 5 5 1 Enterprise 使用 script 开
  • 使用 QTestLib 时抑制 qDebug

    我正在向 Qt 中的项目添加单元测试 并希望使用 QTestLib 我已经设置了测试并且它们运行良好 问题是在项目中我们重写了 qDebug 以输出到我们自己的日志文件 这在运行应用程序时效果很好 问题是当我测试类时 它有时会开始记录 然后
  • QWebView等待加载

    bool MainWindow waitForLoad QWebView view QEventLoop loopLoad QTimer timer QObject connect view SIGNAL loadFinished bool
  • QGraphicsView 在完整布局中未最大化

    I have following GUI having four QGraphicView objects 正如您在每个视图下看到的那样 它有四个工具按钮 为了最大化视图 我连接了工具按钮的信号来隐藏其他三个视图的插槽 并将大小策略设置为扩
  • 如何改善 Qt5 程序的启动时间?

    我最近切换到 Qt5 我注意到与 Qt4 相比 初始化 QApplication 花费的时间明显更长 大约几分钟 仔细一看 程序似乎把时间花在了这里 Qt5Guid dll QGlobalStatic

随机推荐

  • 数组的初识

    目录 1 初识数组 2 数组的简单操作 2 1读取元素 2 2更新元素 2 3插入元素 2 4删除元素 1 初识数组 数组是有限个相同类型的变量所组成的有序集合 数组中的每一个变量被称为元素 数组是最简单 最为常用的数据结构 以整型数组为例
  • HTML5全栈工程师好就业吗

    2017突然流行起来的一个新职位 全栈工程师 大概在很多人眼里 全栈工程师是一个全能人才 事实的确如此 以web前端为主 需求 后台 前台 用户 设计等内容为辅 全栈工程师拥有更广阔的视野和更广泛的学识 全栈工程师可以从更高的角度去看待问题
  • 基于FPGA的卷积神经网络实现(一)简介

    目录 简介 框架 资源分配 1 资源分配 2 数据量化 1 数据量化 2 数据读写 卷积模块 池化 全连接与输出 事先声明 仅用于记录和讨论 有任何问题欢迎批评指正 只是觉得菜的大佬们请绕路 就不用在这里说大实话了 因为本身就是一个粗糙的d
  • 2021-11-16尤破金11.16黄金原油今日行情涨跌趋势分析及周二多空操作建议布局

    黄金最新行情分析 黄金消息面解析 周一现货黄金持稳于1863附近 上周五金价探底回升并实现七连涨 受到美国消费信心大幅下滑和美元走软的支撑 自11月以来 金价已上涨高达110美元 这得益于对通胀的担忧加深 以及主要央行保证将暂时把利率保持在
  • jsp页面获取参数的方法(url解析、el表达式赋值、session取值)【原创】

    最近使用myEclispse做网站 使用jsp js css做页面 网站中常用到从列表进入详情页面的跳转 下面对详情页面的值填充方式做一个简单总结 1 url中使用 request获取参数 jsp上方添加type参数
  • 23个CVPR 2020收录的新数据集,都在这里了!

    编辑 Amusi Date 2020 06 20 来源 CVer微信公众号 链接 23个CVPR 2020收录的新数据集 都在这里了 前言 Amusi 之前整理了1467篇CVPR 2020所有论文PDF下载资源 以及300篇 CVPR 2
  • HBuilder html 乱码解决,java eclipse等应当同理

    1 网上下载了一套html代码 出现乱码 一般就是编码格式问题 2 解决方式 更改编码 3 剪切所有内容 然后右下角修改编码为utf 8 4 再粘贴内容 5 访问页面
  • (必行方案)PPT快捷键复制一次粘贴两次问题

    问题 复制的时候复制一次 粘贴的时候在Word Excel都正常但是PPT里面不正常 只有使用PPT的时候出现粘贴两次的问题 Word和Excel中Ctrl C后Ctrl V粘贴一次 没有问题 PPT中Ctrl V时粘贴2次 而用右键粘贴方
  • 系数矩阵与系统稳定性的关系

    对连续时间线性定常控制系统而言 系统内部渐近稳定的充分必要条件是其系数矩阵A的特征值都在复平面的左半开平面内 对连续时间线性定常控制系统而言 系统输入 输出稳定的充分必要条件是其特征方程的根 传递函数的极点 全都在复平面的左半平面内 离散时
  • Linux的简单介绍

    LINUX操作系统是一种免费使用和自由传播的类UNIX操作系统 其内核由林纳斯 托瓦兹于1991年10月5日首次发布 是一个基于POSIX的多用户 多任务 支持多线程和多CPU的操作系统 它能运行主要的Unix工具软件 应用程序和网络协议
  • 03-03 周五 镜像安装sshd和jupyter以及修改密码

    03 03 周五 镜像安装sshd和jupyter以及修改密码 时间 版本 修改人 描述 2023年3月3日15 34 49 V0 1 宋全恒 新建文档 简介 由于在镜像中需要进行jupyter和sshd的安装 并且需要进行密码的修改 因此
  • 在 Windows 10下安装Flutter+Dart+Android Studio 配置Flutter开发环境

    在 Windows 10下安装Flutter Dart Android Studio 配置Flutter开发环境 文章首发地址 配置环境变量 由于部分网站被墙的原因 我们需要先配置Flutter国内镜像地址 这两个地址是由Flutter官方
  • html css开关按钮样式,纯CSS实现开关按钮

    上面这种开关按钮在现代网页UI设计中经常出现 代替了以前丑陋的checkbox 在很多UI框架中如elementUI都有组件可以直接使用 但是画出这样一个开关是十分简单的 不需要借助JS代码就可以实现 核心思路就是将原有input框进行隐藏
  • github响应时间过长且修改hosts无效【解决办法】

    打开ipaddress com 分别键入 github global ssl fastly net 和 github com 查询到对应的IP地址 打开hosts文件 并新增 hosts文件地址 win下 C Windows System3
  • 我提交的第一个Flink commit - Flink 闭包检查

    为什么闭包 Flink中算子都是通过序列化分发到各节点上 所以要确保算子对象是可以被序列化的 算子的成员变量 代码中的匿名内部类都是检查的范围 闭包检查入库 被调用的入口是 StreamExecutionEnvironment clean
  • Typora 常用快捷键

    文章目录 Typora 常用快捷键 一 菜单栏 二 文件 三 编辑 四 段落 五 格式 六 视图 七 设置颜色 Typora 常用快捷键 一 菜单栏 文件 alt F 编辑 alt E 段落 alt P 格式 alt O 视图 alt V
  • cahtgpt有哪些优势

    ChatGPT丨小智ai丨chatgpt丨人工智能丨OpenAI丨聊天机器人丨AI语音助手丨GPT 3 5丨开源AI平台 ChatGPT是一种基于深度学习技术的自然语言处理模型 它可以自主地从大量的文本数据中学习和理解自然语言 从而实现自然
  • hbuildx中使用真机调试

    前言 使用真机调试的原因是我开发uni app项目 调试一直是在浏览器中选择手机模式进行调试的 但是打包安装到手机以后 发现很多样式变化很大 完全不符合预期 这时我知道浏览器是不能完全匹配手机的效果的 模拟器 于是我开始找模拟器 市面上模拟
  • Dictionary字典类使用范例

    原文发布时间为 2009 11 04 来源于本人的百度文章 由搬家工具导入 using System using System Web UI WebControls using System Collections Generic publ
  • Qt

    参考博客 QThread必须要了解的几个函数 https blog csdn net t46414704152abc article details 52155777 设计思路 读文件生成sql语句写入内存为一个线程 返回sql语句给主线程