一 Qt线程与进程概述

线程与进程对比

特性线程 (QThread)进程 (QProcess)
内存空间共享父进程内存独立内存空间
创建开销小 (几MB)大 (几十MB)
通信方式共享内存/信号槽管道/套接字/文件
崩溃影响导致整个进程终止仅自身终止
适用场景高并发任务、计算密集型隔离第三方应用、安全需求

二 Qt线程

1. 基本概念

  • 线程:程序执行的最小单元,共享相同内存空间

  • QThread:Qt中线程管理的核心类

  • 线程安全:多线程访问共享资源时需同步

 2. 创建方式(四种)

  • 继承QThread类,重写run()方法

  • 使用moveToThread将一个继承QObject的子类对象移至线程,内部槽函数均在子线程中执行

  • 使用QThreadPool,搭配QRunnable (线程池)

  • 使用QtConcurrent(线程池)

n. 线程创建

1. QThread,重写run()

#include <QThread>
#include <QDebug>class WorkerThread : public QThread {Q_OBJECT
protected:void run() override {for (int i = 0; i < 5; ++i) {qDebug() << "Thread working:" << i;sleep(1);  // 模拟耗时操作}}
};// 使用
int main() {WorkerThread thread;thread.start();  // 启动线程thread.wait();   // 等待线程结束return 0;
}

2. moveToThread

#include <QObject>
#include <QThread>
#include <QDebug>class Worker : public QObject {Q_OBJECT
public slots:void doWork() {for (int i = 0; i < 5; ++i) {qDebug() << "Worker in thread:" << QThread::currentThreadId();QThread::sleep(1);}emit workDone();}
signals:void workDone();
};// 使用
int main() {QThread thread;Worker worker;worker.moveToThread(&thread);  // 关键步骤QObject::connect(&thread, &QThread::started, &worker, &Worker::doWork);QObject::connect(&worker, &Worker::workDone, &thread, &QThread::quit);thread.start();thread.wait();return 0;
}

3. QThreadPool(线程池)

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QThreadPool"
#include "MyTask.cpp"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mytask.cpp"
#include "QThreadPool"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//新建10个任务,提交给线程池//方式1: 全局线程池:一个项目中只有一个线程池,有时候整个项目有有可能有多个//QThreadPool *pool =    QThreadPool::globalInstance();//方式2:新建线程池QThreadPool *pool = new QThreadPool;for(int i=0;i<10;i++){pool->start( new MyTask());}}MainWindow::~MainWindow()
{delete ui;
}}MainWindow::~MainWindow()
{delete ui;
}#include <QRunnable>
#include <QDebug>
#include <QThread>
class MyTask : public QRunnable
{//重写run方法void run() override{qDebug()<< QThread::currentThread() << "running .....";}};

4. QtConcurrent(线程池)

三 Qt进程

1. 基本概念

  • 进程:独立内存空间的程序实例

  • QProcess:用于启动和控制外部程序

进程是一个应用程序被操作系统拉起来加载到内存之后从开始执行到执行结束的这样一个过程。简单来说,进程是程序(应用程序,可执行文件)的一次执行。进程通常由程序、数据和进程控制块(PCB)组成。比如双击打开一个桌面应用软件就是开启了一个进程。

传统的进程有两个基本属性:可拥有资源的独立单位;可独立调度和分配的基本单位。对于这句话我的理解是:进程可以获取操作系统分配的资源,如内存等;进程可以参与操作系统的调度,参与CPU的竞争,得到分配的时间片,获得处理机(CPU)运行。

进程在创建、撤销和切换中,系统必须为之付出较大的时空开销,因此在系统中开启的进程数不宜过多。比如你同时打开十几个应用软件试试,电脑肯定会卡死的。于是紧接着就引入了线程的概念

四 sqlite数据库

  sqlite十个轻量级的数据库,如果要进行嵌入式的开发,像mysql,与Oracle像这样的中大型关系库是不太现实的,因为嵌入式大部分的工作,还是以轻量级的项目为主,尽可能的节约空间,完成项目,sqlite可以不用他的专属服务器就可以使用,它可以以一个文件为库,可以还可以用sql的语句,兼顾效率的同时,也极致的轻量化。

  在此我认为只需要写两个项目即可,一是如何链接数据库,二是如何进行增删改查。

1. 连接数据库

其实我建议将连接数据库的语句单独写个类出来,这样简化操作,上上选。

1. 在我的project.pro的上方添加 

QT       += core gui sql 

2. 引入头

#include <QSqlDatabase>
#include <QSqlError> //sql错误信息头文件
#include <QSqlQuery> //sql查询头文件
  QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");// 链接数据库db.setDatabaseName("D:/360MoveData/Users/HP/Desktop/sqlite_db/test.db");if (db.open() == false){qDebug() << "数据库打开失败";return;}else{qDebug() << "数据库打开成功";// 新建tableQSqlQuery query;QString sql = "create table if not exists user(id int primary key, name varchar(20))";if (query.exec(sql)){qDebug() << "表格创建成功";// 向user插入数据sql = "insert into user(id, name) values(1, '张三')";if (query.exec(sql)){qDebug() << "数据插入成功";// 查询数据sql = "select * from user";if (query.exec(sql)){qDebug() << "数据查询成功";// 输出到qDebugwhile (query.next()){qDebug() << query.value(0).toInt() << query.value(1).toString();}}else{qDebug() << "数据查询失败";}}else{qDebug() << "数据插入失败";}}else{qDebug() << "表格创建失败";qDebug() << query.lastError().text();}}
}

2. 增删改查示例

这个写了个dao来进行数据库的处理,相信大家可以看的懂,其实不难。仔细看一看。

#include "studentdao.h"/*** @brief 构造函数* 获取数据库连接*/
StudentDAO::StudentDAO(): m_db(DatabaseManager::getInstance()->getDatabase())
{
}/*** @brief 添加学生* @param student 学生对象* @return 添加成功返回true,否则返回false*/
bool StudentDAO::addStudent(const Student &student)
{if (!m_db.isOpen()){qDebug() << "添加学生失败:数据库未连接";return false;}QSqlQuery query(m_db);// 使用参数化查询,防止SQL注入query.prepare("INSERT INTO student (id, name) VALUES (:id, :name)");query.bindValue(":id", student.id());query.bindValue(":name", student.name());if (query.exec()){qDebug() << "添加学生成功:ID=" << student.id() << ", 姓名=" << student.name();return true;}else{qDebug() << "添加学生失败:" << query.lastError().text();return false;}
}/*** @brief 删除学生* @param id 学生ID* @return 删除成功返回true,否则返回false*/
bool StudentDAO::deleteStudent(int id)
{if (!m_db.isOpen()){qDebug() << "删除学生失败:数据库未连接";return false;}QSqlQuery query(m_db);query.prepare("DELETE FROM student WHERE id = :id");query.bindValue(":id", id);if (query.exec()){if (query.numRowsAffected() > 0){qDebug() << "删除学生成功:ID=" << id;return true;}else{qDebug() << "删除学生失败:未找到ID为" << id << "的学生";return false;}}else{qDebug() << "删除学生失败:" << query.lastError().text();return false;}
}/*** @brief 更新学生信息* @param student 学生对象* @return 更新成功返回true,否则返回false*/
bool StudentDAO::updateStudent(const Student &student)
{if (!m_db.isOpen()){qDebug() << "更新学生失败:数据库未连接";return false;}QSqlQuery query(m_db);query.prepare("UPDATE student SET name = :name WHERE id = :id");query.bindValue(":name", student.name());query.bindValue(":id", student.id());if (query.exec()){if (query.numRowsAffected() > 0){qDebug() << "更新学生成功:ID=" << student.id() << ", 新姓名=" << student.name();return true;}else{qDebug() << "更新学生失败:未找到ID为" << student.id() << "的学生";return false;}}else{qDebug() << "更新学生失败:" << query.lastError().text();return false;}
}/*** @brief 根据ID查询学生* @param id 学生ID* @return 学生对象,如果不存在返回空对象*/
Student StudentDAO::getStudentById(int id)
{Student student;if (!m_db.isOpen()){qDebug() << "查询学生失败:数据库未连接";return student;}QSqlQuery query(m_db);query.prepare("SELECT id, name FROM student WHERE id = :id");query.bindValue(":id", id);if (query.exec() && query.next()){student.setId(query.value(0).toInt());student.setName(query.value(1).toString());qDebug() << "查询学生成功:ID=" << student.id() << ", 姓名=" << student.name();}else{qDebug() << "查询学生失败:未找到ID为" << id << "的学生";}return student;
}/*** @brief 查询所有学生* @return 学生对象列表*/
QList<Student> StudentDAO::getAllStudents()
{QList<Student> students;if (!m_db.isOpen()){qDebug() << "查询所有学生失败:数据库未连接";return students;}QSqlQuery query("SELECT id, name FROM student", m_db);while (query.next()){Student student;student.setId(query.value(0).toInt());student.setName(query.value(1).toString());students.append(student);}qDebug() << "查询所有学生成功,共" << students.size() << "条记录";return students;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/86045.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/86045.shtml
英文地址,请注明出处:http://en.pswp.cn/web/86045.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机视觉阶段一:CV入门基础

目录 学习目标&#xff1a; 一、核心知识点 二、实用工具推荐 三、学习内容与步骤 1.环境搭建 2.图像获取与显示 3 图像基础处理 4 图像几何变换 5 图像像素操作 四、实战任务建议 实战 1&#xff1a;图像加载 显示 保存 实战 2&#xff1a;灰度图 边缘检测 图…

新增MCP接入和AutoAgent,汉得灵猿AI中台1.6版正式发布!

汉得灵猿&#xff08;大圣&#xff09;AI中台1.6版本&#xff0c;经过数月迭代&#xff0c;现已正式发布&#xff01; 新版本最被期待的新功能&#xff0c;无疑是4月份预告的MCP接入&#xff0c;而令人同样激动的另一项新功能&#xff0c;则是AutoAgent动态规划智能体。除了两…

总结汇报思路

一、明确汇报目标 受众需求&#xff1a;领导/客户/团队最关心什么&#xff1f;&#xff08;结果&#xff1f;问题&#xff1f;下一步计划&#xff1f;&#xff09; 核心目的&#xff1a;展示成果&#xff1f;争取资源&#xff1f;总结经验&#xff1f;解决问题&#xff1f; 时…

文件锁的艺术:深入解析 `fcntl(F_SETLK/F_GETLK)`

引言&#xff1a;在共享资源时代守护数据一致性 在多进程/多线程的应用场景中&#xff0c;文件作为一种共享资源常常面临被并发访问的挑战。想象一个数据库系统&#xff0c;多个客户端可能同时尝试修改同一数据文件&#xff1b;或者一个配置文件&#xff0c;需要确保在更新时不…

一个免费的视频、音频、文本、图片多媒体处理工具

大家好&#xff0c;我是小悟。 给大家推荐一款可以免费使用的视频、音频、文本、图片处理工具&#xff0c;名字叫百创工坊&#xff0c;不用下载&#xff0c;不用注册&#xff0c;有免费的用就赶紧薅吧。 视频工具 提取音频&#xff1a;从视频中提取音频文件&#xff0c;支持多…

在 ef core 中操作复杂类型的序列化和反序列化时,如何全局设置 utf-8 编码避免中文字符被转义?

我们在使用 Entity Framework Core&#xff08;EF Core&#xff09; 时&#xff0c;如果希望 全局设置 JSON 序列化和反序列化使用 UTF-8 编码&#xff0c;通常需要配置 System.Text.Json 的默认行为&#xff0c;因为 EF Core 6.0 及以上版本默认使用 System.Text.Json 进行 JS…

WPF CommunityToolkit.Mvvm 信使 (ObservableRecipient)

WPF CommunityToolkit.Mvvm 中的 ObservableRecipient 是什么&#xff1f; ObservableRecipient 是 .NET Community Toolkit MVVM 库中的一个核心类&#xff0c;继承自 ObservableObject。它专为 WPF 应用设计&#xff0c;提供以下核心功能&#xff1a; 基础数据绑定支持&am…

《C++》命名空间简述

文章目录 一、命名空间定义二、访问命名空间内的成员三、标准命名空间:std四、嵌套命名空间 一、命名空间定义 在C中&#xff0c;命名空间&#xff08;namespace)是一种将标识符分组的机制&#xff0c;用于避免重命名。例如&#xff1a; int a 3;int main() {int a 0;print…

【路径规划】基于Matlab的改进RRT算法二维/三维路径规划

基于Matlab的改进RRT算法二维/三维路径规划 一、引言 在机器人学、自动驾驶等领域&#xff0c;路径规划是一个关键问题&#xff0c;它旨在为机器人或车辆找到一条从起始点到目标点的安全、高效的路径。RRT&#xff08;Rapidly-exploring Random Trees&#xff09;算法作为一种…

PHP的命名空间与自动加载机制

在PHP 5.3版本之后&#xff0c;引入了命名空间的概念&#xff0c;这为解决全局命名冲突和促进代码的模块化提供了强有力的工具。命名空间允许开发者将类、函数和常量封装在不同的命名空间中&#xff0c;从而避免了全局范围内的名称冲突问题。 命名空间基础 命名空间在PHP中是…

OpenSIPS 邂逅 Kafka:构建高效 VoIP 消息处理架构

使用场景使用步骤 引入模块组装&发送数据消费数据故障转移 使用场景 异步日志处理&#xff1a;将 OpenSIPS 中的 SIP 信令日志、通话记录&#xff08;CDR&#xff09;等数据发送到 Kafka 队列中。 事件通知与监控&#xff1a;利用 OpenSIPS 的 event_interface 模块将 S…

《AI大模型应用技术开发工程师》学习总结

以下是对你提供的《AI大模型应用技术开发工程师》课程内容的系统梳理&#xff0c;已去除所有广告、价格、报名、个人信息等内容&#xff0c;并补全了技术要点&#xff0c;最后给出客观的学习建议和个人感想&#xff0c;适合公开分享或自我学习参考。 AI大模型应用技术开发工程师…

Python爬虫实战:研究LOSO相关技术

1. 引言 1.1 研究背景与意义 随着互联网数据的爆炸式增长,个性化推荐系统成为提升用户体验的关键技术。准确捕捉用户兴趣需要大量多维度数据,但获取高质量标注数据面临隐私保护、数据分散等挑战。网络爬虫技术为自动采集用户行为数据提供了解决方案,而如何有效评估模型在个…

stm32万年历仿真+keil5程序

stm32万年历 本设计是利用单片机实现一个简易万年历系统&#xff0c;能够准确显示时、分、秒信息。用户可通过特定按键对时间进行设置调整&#xff0c;具备基本的时间校准功能&#xff0c;可满足日常简易计时需求。运用了stm32单片机模块内部定时器 / 计数器功能来实现精确计时…

操作系统--名称解释

第一章: 操作系统:位于硬件层之上,所有软件层之下的一个系统软件,是管理系统中各种软硬件资源,方便用户使用计算机系统的程序集合 并发:宏观上是同时发生,但是再微观是交替发生的(若干事件在同一时间间隔内发生,单CPU) 并行:微观上同时发生(要求多个CPU) 共享:系统的资源可以…

2025.6.16-实习

2025.6.18--2025.6.23 1.使用Cocos&#xff0c;从0开发老虎棒子鸡2D游戏。实现&#xff1a;AI自动选择&#xff0c;倒计时&#xff0c;对战逻辑&#xff0c;播放动画&#xff0c;设置背景音乐等功能。 2.使用Cocos&#xff0c;开发2D手术游戏。实现&#xff1a;视频、音频控制播…

构建你的 AI 模块宇宙:Spring AI MCP Server 深度定制指南

引言&#xff1a;当模块化遇见 AI 在微服务架构的海洋中&#xff0c;MCP&#xff08;Module Communication Protocol&#xff09;就像一艘智能帆船&#xff0c;它让不同 AI 模块的通信变得优雅而高效。本文将带你构建一艘属于自己的 AI 智能帆船——自定义 Spring AI MCP Serv…

从数据到洞察:UI前端如何利用大数据优化用户体验

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在当今数字化时代&#xff0c;数据如同蕴藏着无限价值的宝藏&#xff0c;源源不断地产生并积累…

SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案

SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案 在嵌入式系统中存储大型媒体文件需要平衡存储效率、访问速度和资源限制。以下是针对嵌入式C环境的优化方案&#xff1a; 一、存储策略选择 1. 直接存储 vs 文件路径存储 方法优点缺点适用场景BLOB直接存储数据一致性高…

区块链技术概述:从比特币到Web3.0

目录 区块链技术概述&#xff1a;从比特币到Web3.0引言&#xff1a;数字革命的下一篇章1. 区块链技术基础1.1 区块链定义与核心特征1.2 区块链数据结构可视化 2. 比特币&#xff1a;区块链的开端2.1 比特币的核心创新2.2 比特币交易生命周期 3. 以太坊与智能合约革命3.1 以太坊…