045_第三代软件开发-U盘监测

头图

第三代软件开发-U盘监测

文章目录

  • 第三代软件开发-U盘监测
    • 项目介绍
    • U盘监测
      • 原理解释
      • 源代码

关键字: QtQmlUSBDisk文件

项目介绍

欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。

在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。

在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资源消耗,以确保我们的项目在各种平台和设备上都能够高效运行。

无论您是对 QML 和 C++ 开发感兴趣,还是需要我们为您构建复杂的用户界面和后端逻辑,我们都随时准备为您提供支持。请随时联系我们,让我们一同打造现代化、高性能的 QML & C++ 项目!

重要说明☝

☀该专栏在第三代软开发更新完将涨价

U盘监测

一个项目在前期研究阶段需要的是什么,是理论的支撑,在验证这一理论的时候,需要大量的数据做支撑,所以我们需要软件具备数据记录功能,虽然这些功能不会最终暴露给用户,但是在前期研究阶段是必不可少的,所以我们需要具备这个功能,而这个功能开启的必要条件就是第一要在工程模式,第二要在U盘插入的情况下,才会开启。

而最终交付的用户的需求是需要把用户的报告导出到U盘,因为目前咱的设备是不带打印机的,无法直接打印出报告,而Linux下适配打印机,难度会超过Windows,不是我们不会,而是每家用的打印机都不一样,加上技术支持的技术不在线,所以暂时只是支持用户将报告导出到U盘,后期不排除直接配置打印机或者介入医院标准的HIS系统,不过那都是后话了,今天咱们主要解决USB下U盘监测的问题。

闭坑指南

Linux,每种系统实现的方式类似,又不完全一致,所以一下内用仅适用于Ubuntu 22.04版本,其他系统不做保证,不过原理应该是一致的,稍作改动即可。

原理解释

其实不管什么设备,在连入Linux系统,都会对应出一个文件来,为啥内,Linux 设计哲学之一 一切皆文件,所以我们实现的原理就是检测某一个文件夹的变化,这个Qt就给我们提供了很好的类QFileSystemWatcher,可以直接使用就可以。每个系统U盘设备的挂在有一定差异,自行搞一下就OK了。

源代码

头文件


#include <QObject>#include "T_Core/Turing_FileMonitoring/turing_filesystemwatcher.h"class XXXX : public QObject
{Q_OBJECTQ_PROPERTY(bool usbIn READ usbIn WRITE setUsbIn NOTIFY usbInChanged)                                    // USB插入标志Q_PROPERTY(QString usbPath READ usbPath WRITE setUsbPath NOTIFY usbPathChanged)                         // USB路劲Q_PROPERTY(QString systemPath READ systemPath WRITE setSystemPath NOTIFY SystemPathChanged)             // USB监听文件夹public:explicit XXXX(QObject *parent = nullptr);~XXXX();static XXXX* getInstance();QString getUserName();bool usbIn() const;void setUsbIn(bool newUsbIn);QString usbPath() const;void setUsbPath(const QString &newUsbPath);const QString &systemPath() const;void setSystemPath(const QString &newSystemPath);signals:void usbInChanged();void usbPathChanged();void SystemPathChanged();void signalUmountUSB();public slots:void slotUmountDisk();
private slots:void slot_GetSystemDevByName();void slot_AddSystemDevByName(QString strFolder, QString strFile);void slot_DeleteSystemDevByName(QString strFolder, QString strFile);private:Turing_FileSystemWatcher*                           m_systemWatcher             = nullptr;QString                                             m_systemPath                = "";QStringList                                         m_systemList;bool                                                m_usbIn                     = false;QString                                             m_usbPath                   = ".";};#endif // XXXX_H

源文件

#include "XXXX.h"#include <QProcess>#include <iostream>#include <QTextStream>
#include <QEventLoop>
#include <QTimer>#include <QDir>
#include <QEventLoop>
#include <QTimer>static QTextStream cout(stdout, QIODevice::WriteOnly);Q_GLOBAL_STATIC(XXXX,XXXX)                                      // 单例宏
/*** @brief XXXX::XXXX* @param parent* 构造函数*/
XXXX::XXXX(QObject *parent): QObject{parent}
{m_systemWatcher = new Turing_FileSystemWatcher();connect(m_systemWatcher,&Turing_FileSystemWatcher::signalAddFile,this,&XXXX::slot_AddSystemDevByName);connect(m_systemWatcher,&Turing_FileSystemWatcher::signalDeleteFile,this,&XXXX::slot_DeleteSystemDevByName);connect(this, &XXXX::SystemPathChanged,this,&XXXX::slot_GetSystemDevByName);setSystemPath("/media/" + getUserName());}XXXX::~XXXX()
{}
/*** @brief XXXX::getInstance* @return* 单例接口*/
XXXX *XXXX::getInstance()
{return XXXX;
}
/*** @brief XXXX::getUserName* @return* 获取用户名*/
QString XXXX::getUserName()
{
#ifdef Q_OS_LINUXQStringList envVariables;envVariables << "SUDO_USER.*";QStringList environment = QProcess::systemEnvironment();foreach (QString string, envVariables) {int index = environment.indexOf(QRegExp(string));if (index != -1){QStringList stringList = environment.at(index).split('=');if (stringList.size() == 2){qInfo() << "系统名称获取成功,系统名称: " << stringList.at(1);return stringList.at(1);}}}qWarning() << "系统名称获取失败,默认系统名称: " << "turing";return "turing";
#endif
}/*** @brief XXXX::slot_GetSystemDevByName 初始化检测U盘是否存在*/
void XXXX::slot_GetSystemDevByName()
{QDir dir(m_systemPath);if(!dir.exists())return;dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);dir.setSorting(QDir::Name);m_systemList = dir.entryList();if(m_systemList.size() > 0){setUsbIn(true);// 默认活动U盘为获取的第一个setUsbPath(m_systemPath + "/" + m_systemList.at(0));qInfo() << "初始化获取U盘,U盘路径: " << m_usbPath;}else{setUsbIn(false);}
}/*** @brief XXXX::slot_AddSystemDevByName 插入活动U盘* @param strFolder* @param strFile*/
void XXXX::slot_AddSystemDevByName(QString strFolder, QString strFile)
{if(strFolder != m_systemPath)return;// 判断是否存在活动U盘if(!m_usbIn){QEventLoop loop;//定义一个新的事件循环QTimer::singleShot(100, &loop, SLOT(quit()));  //创建单次定时器,槽函数为事件循环的退出函数loop.exec();  //事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出setUsbPath(m_systemPath + "/" + strFile);setUsbIn(!m_usbIn);qInfo() << "挂在U盘,路径: " << m_usbPath;}
}/*** @brief XXXX::slot_DeleteSystemDevByName 拔出活动U盘* @param strFolder* @param strFile*/
void XXXX::slot_DeleteSystemDevByName(QString strFolder, QString strFile)
{if(strFolder != m_systemPath)return;if(m_usbIn){// 判断拔出的是否是活动U盘if(m_usbPath != m_systemPath + "/" + strFile){return;}setUsbPath("./");setUsbIn(!m_usbIn);qInfo() << "U盘非正常状态卸载,请检查数据完整性!";}else{qInfo() << "U盘正常弹出. 完毕";}
}/*** @brief XXXX::slotUmountDisk  卸载U盘槽函数*/
void XXXX::slotUmountDisk()
{emit signalUmountUSB();QEventLoop loop;//定义一个新的事件循环QTimer::singleShot(1000, &loop, SLOT(quit()));  //创建单次定时器,槽函数为事件循环的退出函数loop.exec();  //事件循环开始执行,程序会卡在这里,直到定时时间到,本循环被退出int ret = system(QString("echo umount '%1'").arg(m_usbPath).toLocal8Bit());if(ret == -1){qInfo() << "卸载U盘失败";}else{setUsbIn(false);qInfo() << "弹出U盘";}
}/*** @brief XXXX::usbIn* @return* 返回USB插入拔出状态*/
bool XXXX::usbIn() const
{return m_usbIn;
}
/*** @brief XXXX::setUsbIn* @param newUsbIn* 设置USB插入拔出状态*/
void XXXX::setUsbIn(bool newUsbIn)
{if (m_usbIn == newUsbIn)return;m_usbIn = newUsbIn;emit usbInChanged();
}
/*** @brief XXXX::usbPath* @return* 返回USB设备路径*/
QString XXXX::usbPath() const
{return m_usbPath;
}
/*** @brief XXXX::setUsbPath* @param newUsbPath* 设置USB设备路径*/
void XXXX::setUsbPath(const QString &newUsbPath)
{if (m_usbPath == newUsbPath)return;m_usbPath = newUsbPath;emit usbPathChanged();
}/*** @brief XXXX::systemPath 返回检测U盘存在路径* @return*/
const QString &XXXX::systemPath() const
{return m_systemPath;
}/*** @brief XXXX::setSystemPath 设置检测U盘存在路径* @param newSystemPath*/
void XXXX::setSystemPath(const QString &newSystemPath)
{if (m_systemPath == newSystemPath)return;m_systemPath = newSystemPath;qInfo() << "新增监控路径:" << m_systemPath;m_systemWatcher ->addWatchPath(m_systemPath);emit SystemPathChanged();
}
  1. 这里需要注意,我使用了Qt的属性系统,我这里有三个属性,这些属性将在QML中被使用。

    Q_PROPERTY(bool usbIn READ usbIn WRITE setUsbIn NOTIFY usbInChanged)                                    // USB插入标志
    Q_PROPERTY(QString usbPath READ usbPath WRITE setUsbPath NOTIFY usbPathChanged)                         // USB路劲
    Q_PROPERTY(QString systemPath READ systemPath WRITE setSystemPath NOTIFY SystemPathChanged)             // USB监听文件夹
    
  2. 第二部就是需要给这个U盘检测模块设置一个监测地址

    void XXXX::setSystemPath(const QString &newSystemPath)
    {if (m_systemPath == newSystemPath)return;m_systemPath = newSystemPath;qInfo() << "新增监控路径:" << m_systemPath;m_systemWatcher ->addWatchPath(m_systemPath);emit SystemPathChanged();
    }
    

    这里搭建看了可一个Turing_FileSystemWatcher,暂时这里可以直接把它理解成为一个Qt的文件监视器,只不过Qt的文件监视器只能知道文件夹变化了,而不能准确返回是增加了、减少了还是修改了,我们自己的Turing_FileSystemWatcher可以分类识别到时增加、减少还是修改,仅此而已,不影响代码阅读。

  3. 接着就是Qt 的事件循环,等待Turing_FileSystemWatcher的信号了。这里就不做具体解释了,代码没有太大难度。看下注释应该没有问题。


博客签名2021

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

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

相关文章

玩转AIGC:如何选择最佳的Prompt提示词?

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Redis02-持久化策略

目录 RDB&#xff08;Redis DataBase Backup file&#xff09; RDB执行原理 AOF&#xff08;Append-Only File&#xff09; RDB和AOF对比 Redis支持多种持久化方式&#xff0c;以确保数据在内存中持久存储&#xff0c;以便在Redis服务器重启时数据不会丢失。Redis中持久化的…

Linux第一个小程序进度条

缓冲区 ​ 在写进度条程序之前我们需要介绍一下缓冲区&#xff0c;缓冲区有两种&#xff0c;输入和输出缓冲区&#xff0c;这里主要介绍输出缓冲区。在我们用C语言写代码时&#xff0c;输出一些信息&#xff0c;实际上是先输出到输出缓冲区里&#xff0c;然后才输出到我们的显…

Python笔记——linux/ubuntu下安装mamba,安装bob.learn库

Python笔记——linux/ubuntu下安装mamba&#xff0c;安装bob.learn库 一、安装/卸载anaconda二、安装mamba1. 命令行安装&#xff08;大坑&#xff0c;不推荐&#xff09;2. 命令行下载guihub上的安装包并安装&#xff08;推荐&#xff09;3. 网站下载安装包并安装&#xff08;…

二维码智慧门牌管理系统升级:一键报警让你的生活更安全!

文章目录 前言一、升级解决方案的特点二、实施步骤 前言 随着科技的不断进步&#xff0c;我们的生活正在逐渐变得更加智能化。可以想象一下&#xff0c;如果你家的门牌也能拥有这种智能升级&#xff0c;将会带来怎样的改变&#xff1f;今天&#xff0c;让我们一起探讨这令人兴…

数据处理中的中心化

数据处理中的中心化&#xff0c;就是将原数据减去平均值&#xff0c;得到新的数据&#xff0c;新的数据的平均值为0。 假设原数据是x&#xff08;x可以是多维的&#xff09;&#xff0c;其平均值是&#xff0c;新的数据&#xff0c;那么新数据的平均值是为0的。下面证明下&…

【云原生基础】了解云原生,什么是云原生?

&#x1f4d1;前言 本文主要讲了云原生的基本概念和原则的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#x…

BO(Business Object)是一种用于表示业务对象的设计模式

1、Service层 BO 1.1、FruitService接口 package com.csdn.fruit.service; import com.csdn.fruit.dto.PageInfo; import com.csdn.fruit.dto.PageQueryParam; import com.csdn.fruit.pojo.Fruit; public interface FruitService {PageInfo<Fruit> getFruitPageInfo(Page…

使用 C# 在Word中插入图表

Word中的图表功能将数据可视化地呈现在文档中。这为展示数据和进行数据分析提供了一种方便且易于使用的工具&#xff0c;使作者能够以直观的方式传达信息。要通过C#代码来实现在Word中绘制图表&#xff0c;可以借助 Spire.Doc for .NET 控件&#xff0c;具体操作参考下文。 目录…

【PC电脑windows-学习样例tusb_serial_device-ESP32的USB模拟串口程序+VScode建立工程+usb组件添加+-基础样例学习】

【PC电脑windows-学习样例tusb_serial_device-ESP32的USB模拟串口程序-基础样例学习】 1、概述2、实验环境3-1、 物品说明3-2、所遇问题&#xff1a;ESP32 cannot open source file "tinyusb.h"或者“tinyusb.h:No such file or directory ....”3-3、解决问题&#…

Flink SQL 窗口聚合详解

1.滚动窗⼝&#xff08;TUMBLE&#xff09; **滚动窗⼝定义&#xff1a;**滚动窗⼝将每个元素指定给指定窗⼝⼤⼩的窗⼝&#xff0c;滚动窗⼝具有固定⼤⼩&#xff0c;且不重叠。 例如&#xff0c;指定⼀个⼤⼩为 5 分钟的滚动窗⼝&#xff0c;Flink 将每隔 5 分钟开启⼀个新…

逆向学习记录(3)工具介绍jadx、gda和jeb

1、jadx 下载地址如下&#xff0c;目前最新版本为v1.4.7&#xff0c;改成想要下载的版本号就能下载对应的版本。 https://github.com/skylot/jadx/releases/tag/v1.4.7 下载后解压&#xff0c;进入对应路径的bin文件夹内&#xff0c;运行jadx-gui.bat。 2、gda 下载地址和gi…

计算机报错找不到msvcp110.dll无法继续执行代码怎么解决?

msvcp110.dll文件丢失是一个相当常见的问题&#xff0c;尤其是在运行某些程序或游戏时。这个问题可能会导致程序无法正常运行&#xff0c;甚至可能导致系统崩溃。那么&#xff0c;面对这样的问题&#xff0c;我们应该如何来解决呢&#xff1f;下面&#xff0c;我将分享我解决问…

OpenGL ES入门教程(二)之绘制一个平面桌子

OpenGL ES入门教程&#xff08;二&#xff09;之绘制一个平面桌子 前言0. OpenGL绘制图形的整体框架概述1. 定义顶点2. 定义着色器3. 加载着色器4. 编译着色器5. 将着色器链接为OpenGL程序对象6. 将着色器需要的数据与拷贝到本地的数组相关联7. 在屏幕上绘制图形8. 让桌子有边框…

pg14-sql基础(三)-分组

分组 SELECT hire_date, COUNT(*) FROM employees GROUP BY hire_date;SELECT extract(year from hire_date), COUNT(*) FROM employees GROUP BY extract(year from hire_date); -- GROUP BY 1;SELECT extract(year from hire_date), department_id, COUNT(*) FROM employees…

UE5——源码阅读——1

UE启动 hInInstance &#xff1a;项目实例 hPrevInstance&#xff1a;项目上一个实例 pCmdLine&#xff1a;参数 nCmdShow&#xff1a;窗口显示 TRACE_BOOKMARK(TEXT(“WinMain.Enter”));&#xff1a;UE用来追踪记录的函数&#xff0c;用于标记应用程序在执行过程中一些特定的…

没想到这么齐全!这份 Python 实战干货yyds

今天我分享一些Python学习神器资料&#xff0c;有需要的小伙文末自行免费领取。 1.200Python练手案例&#xff1a; 2.Python全套视频教程等&#xff1a; 3.浙大Python学习套装&#xff1a; * 4.Python实战案例&#xff1a; 5.Pandas学习大礼包 6.学习手册大礼包 Python知识…

Javascript知识点详解:正则表达式

目录 RegExp 对象 概述 实例属性 实例方法 RegExp.prototype.test() RegExp.prototype.exec() 字符串的实例方法 String.prototype.match() String.prototype.search() String.prototype.replace() String.prototype.split() 匹配规则 字面量字符和元字符 转义符…

读程序员的制胜技笔记04_有用的反模式(下)

1. 重新发明轮子 1.1. 发明家的特质就是要用质疑的心态对待所有事物&#xff0c;你从未停下质疑&#xff0c;那你将不可避免地成为一个发明家 1.2. 并非所有的事情都有现成的轮子可以拿来用 1.3. 自己重新写一个新的API&#xff0c;最终调用你使用的库 1.3.1. 你的API应该是…

手动制作Docker容器镜像

文章目录 手动制作Docker容器镜像说明前期准备制作镜像1.启动一个centos系统的容器2.在centos容器中源码安装httpd服务3.基于已经安装好httpd服务的centos容器制作一个httpd镜像4.验证制作出来的镜像的功能5.上传至自己的docker镜像仓库&#xff08;可选&#xff09; 手动制作D…