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

这篇具有很好参考价值的文章主要介绍了045_第三代软件开发-U盘监测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

045_第三代软件开发-U盘监测,# 一个真实的QML&C++项目,qt,qml,U盘,磁盘,DIsk

第三代软件开发-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了。

045_第三代软件开发-U盘监测,# 一个真实的QML&C++项目,qt,qml,U盘,磁盘,DIsk

源代码

头文件


#include <QObject>

#include "T_Core/Turing_FileMonitoring/turing_filesystemwatcher.h"


class XXXX : public QObject
{
    Q_OBJECT
    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监听文件夹

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_LINUX
    QStringList 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的信号了。这里就不做具体解释了,代码没有太大难度。看下注释应该没有问题。文章来源地址https://www.toymoban.com/news/detail-745187.html


045_第三代软件开发-U盘监测,# 一个真实的QML&amp;C++项目,qt,qml,U盘,磁盘,DIsk

到了这里,关于045_第三代软件开发-U盘监测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何制作一个软件开发小程序

    在今天的数字化时代,软件开发行业火热,越来越多的人投身其中。如果你是一个对软件开发感兴趣的新手,你可能会想知道如何制作一个软件开发小程序。在本文中,我将向你介绍如何制作一个简单但功能强大的软件开发小程序,帮助你入门并开始你的编程之旅。 要制作一

    2024年01月24日
    浏览(36)
  • 开发一个软件的主要流程

    本文重点解决如下问题:开发一个软件的主要流程是什么? 了解开发一个软件的主要流程对于编程者而言非常重要,它能够让编程者对如何开发一个软件有个整体的认知。开发一个软件的主要流程包括:1)软件前端界面设计;2)后台功能实现;3)前端和后台联合测试;4)

    2024年02月16日
    浏览(30)
  • 如何开发一个软件

    主要有两个文档,一个需求规格说明书和一个产品原型图 UI设计、数据库设计、接口设计 项目代码编写、单元测试 测试用例、测试报告 软件环境安装、配置 对整个项目负责,任务分配,把控进度,管理型角色 进行需求调研,输出需求调研文档、产品原型等 根据产品原型输

    2024年02月16日
    浏览(43)
  • 数据驱动开发模式将软件开发过程改造成一个公式化的迭代模式,可以提升软件开发效率,缩短开发周期,降低开发成本。

    作者:禅与计算机程序设计艺术 随着云计算、大数据等新兴技术的应用,软件开发领域迎来了蓬勃发展的时期。各种编程语言、框架、工具不断涌现,协同工作的强烈需求已经成为当今社会的一个主要挑战。这就需要一种新的开发方式来适应这种复杂多变的环境。传统的瀑布

    2024年02月06日
    浏览(46)
  • 直播软件app开发:如何开发一个可以免费打扑克的直播应用?

    作为一个技术开发人员,我深知直播软件app开发的重要性。在这个数字化时代,越来越多的人选择使用直播软件来分享自己的生活和与朋友互动。而随着技术的发展,直播软件也不断更新和改进,为用户提供更好的体验和功能。 对于开发者来说,以视频直播app源码为基础进行

    2024年02月16日
    浏览(47)
  • 《移动软件开发》实验一:第一个微信小程序

    1、学习使用快速启动模板创建小程序的方法;2、学习不使用模板手动创建小程序的方法。 1.自动生成小程序 1.1 项目创建 ​ 双击微信开发者工具图标,使用管理员微信扫码二维码后进入菜单画面,选择菜单中的“小程序”选项进入小程序项目管理页面。依次填写项目名称(

    2024年02月10日
    浏览(34)
  • 一个.Net Core开发的开源动态壁纸软件

    推荐一个Github上Start超过10.8K的超火、好用、强大的、内置很多优美的动态壁纸软件。 这是基于.Net Core+WPF开发的、开源的动态壁纸软件,壁纸设置支持任何文件形式,包括:本地视频、网络视频、图片、Html、网络、Unity单机游戏、Godot游戏等;还支持自定义壁纸的属性,自定

    2024年02月05日
    浏览(36)
  • python界面开发案例:制作一个计算器软件

    前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 在我们手机上大家都有一个计算器,对吧 那它这功能是怎么实现的呢? 今天我们在电脑上来实现一个电脑端计算器界面~ 开发环境: Python 3.8 / 编译器 Pycharm 2021.2版本 / 编辑器 本文所有模块环境源码教程皆可点击文章下方

    2023年04月16日
    浏览(39)
  • 《移动软件开发》实验1:第一个微信小程序 实验报告

    本实验报告所参考实验文档为:Docs (feishu.cn) 如想获得详细的制作过程,请点击上面链接。该博客仅为个人使用实验报告 姓名和学号? / 本实验属于哪门课程? 中国海洋大学22夏《移动软件开发》 实验名称? 实验1:第一个微信小程序 博客地址? / Github仓库地址? / (备注:

    2024年02月10日
    浏览(28)
  • WinFrom、C# 学习记录五 开发一个鼠标自动点击小软件

            经常会被问到需要点击软件的,主要都是玩游戏的盆友,但是也有其它用途的。所以简单弄了一个,打算每当有时间,有需求,就加一些小功能。         这里主要是要记录一下相关开发工作,也记录一些使用/更新的信息。         【2022/08/22】版本v1.0(初始版

    2024年02月16日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包