Linux QTC++ 使用bash检测USB设备并且打开目录和文件

Linux QTC++ 使用bash检测USB设备并且打开目录和文件,第1张

写在开头
  1. 使用QProcess类打开外部程序并与之交互通信。
  2. 使用QDirIterator类浏览目录内容并且显示在QListView内。
  3. 使用QFlie类读写文件。
具体设计
  • 检测USB设备是否插入,插入后可进入USB目录内的文本文件(.txt/.sh)并且显示在界面上。
  • 选择界面上显示的文件可以打开查看和修改内容。
  • 拔出USB会回到初始界面。
代码文件

1.checkusbform类
  1. 创建一个bash进程
  2. 每秒给bash发送[df -hT]根据返回值检测是否存在sdb设备,存在的话Enable按钮
  3. 点击PushButton创建openDir类,传递sdb的路径给openDir
  4. 接收openDir的退出信号,收到后退出openDir界面回到checkusbform界面。

checkusbform.ui
checkusbform.h

#ifndef CHECKUSBFORM_H
#define CHECKUSBFORM_H
#include "opendir.h"
#include 
#include 
#include 
#include 
#include 
#include 

namespace Ui {class CheckUsbForm;}
class CheckUsbForm : public QWidget
{
    Q_OBJECT
public:
    explicit CheckUsbForm(QWidget *parent = nullptr);
    ~CheckUsbForm();
    void timerEvent(QTimerEvent *event);//每秒给bash发命令去检测sdb设备
private:
    Ui::CheckUsbForm *ui;
    QProcess *m_proces_bash;
    QString UsbPath;
    bool isHaveUsbDevice;
    int checkUsbDeviceTime;
    openDir *Dir;
private slots:
    void readBashStandardOutputInfo();//接收bash的正常返回信息
    void readBashStandardErrorInfo(); //接收bash的错误返回信息
    void sendInfoToBash();            //给bash发命令
    void on_pushButton_clicked();
    void DirExitSlot();
signals:
    void NoUsbDevice();
};
#endif // CHECKUSBFORM_H

checkusbform.cpp

#include "checkusbform.h"
#include "ui_checkusbform.h"
//1.创建一个bash进程
//2.每秒给bash发送[df -hT]根据返回值检测是否存在sdb
//3.存在的话Enable PushButton
//4.点击PushButton创建openDir类,传递sdb的路径给openDir
//5.接收openDir的退出信号
CheckUsbForm::CheckUsbForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CheckUsbForm)
{
    ui->setupUi(this);
    Dir = new openDir();
    isHaveUsbDevice = 0;
    ui->pushButton->setDisabled(true);
    m_proces_bash = new QProcess;
    m_proces_bash->start("bash");//启动外部程序bash
    m_proces_bash->waitForStarted();//阻塞,直到程序打开
    connect(m_proces_bash,SIGNAL(readyReadStandardOutput()),this,SLOT(readBashStandardOutputInfo()));
    connect(m_proces_bash,SIGNAL(readyReadStandardError()),this,SLOT(readBashStandardErrorInfo()));

    sendInfoToBash();
    checkUsbDeviceTime = startTimer(1000);
}

CheckUsbForm::~CheckUsbForm()
{
    delete ui;
}

//每秒都去检测USB路径
void CheckUsbForm::timerEvent(QTimerEvent *event)
{
    if(event->timerId() == checkUsbDeviceTime)
    {
        sendInfoToBash();
        if(!isHaveUsbDevice)//标志位一旦被改变
        {
            emit NoUsbDevice();//发送USB设备拔出的信息
            this->show();
            ui->pushButton->setDisabled(true);
            disconnect(this,SIGNAL(NoUsbDevice()),Dir,SLOT(FuncExit()));
        }
    }
}

//收到bash正确的返回信息的槽函数
void CheckUsbForm::readBashStandardOutputInfo()
{
    QByteArray cmdout = m_proces_bash->readAllStandardOutput();
    if(!cmdout.isEmpty())
    {
        //识别是否存在"sdb*" 有的话就把U盘路径存下来,这样写其实不严谨
        //这里是根据输入[]的返回信息来处理的
        QString bash_result = QString::fromLocal8Bit(cmdout);
        if(bash_result.contains("sdb"))
        {
            bash_result = bash_result.section("\n",-2);
            bash_result.chop(1);                   //删除最后一个\n,此时获得的字符串就是sdb的信息
            //qDebug()<
            UsbPath = bash_result.section("% ",-1);//%后面的信息是sdb的路径
            //qDebug()<
            if(!UsbPath.isEmpty())
            {
                isHaveUsbDevice = 1;
                ui->pushButton->setDisabled(false);
            }
        }
        else
        {
            isHaveUsbDevice = 0;
            qDebug()<<"no usb device!";
        }
    }
}

//收到bash有误的返回信息的槽函数
void CheckUsbForm::readBashStandardErrorInfo()
{
    QByteArray cmdout = m_proces_bash->readAllStandardError();
    if(!cmdout.isEmpty())
    {
        qDebug()<<"bash recive error info...";
        isHaveUsbDevice = 0;//一旦收到错误信息 就判断为USB设备拔出
    }
}

//主动发送信息给bash
void CheckUsbForm::sendInfoToBash()
{
    //发送命令[df -hT]给bash进程
    QString strCmd = "df -hT";
    m_proces_bash->write(strCmd.toLocal8Bit() + '\n');
}

//点击按钮打开USB目录
void CheckUsbForm::on_pushButton_clicked()
{
    if(isHaveUsbDevice && !UsbPath.isEmpty())
    {
        Dir->open_dir(UsbPath);
        Dir->show();
        this->hide();
        connect(this,SIGNAL(NoUsbDevice()),Dir,SLOT(FuncExit()));
        connect(Dir,SIGNAL(DirExit()),this,SLOT(DirExitSlot()));
    }
}

//关闭USB目录
void CheckUsbForm::DirExitSlot()
{
    this->show();
    disconnect(this,SIGNAL(NoUsbDevice()),Dir,SLOT(FuncExit()));
    disconnect(Dir,SIGNAL(DirExit()),this,SLOT(DirExitSlot()));
}
2.openDir类
  1. 使用QDirIterator遍历sdb路径的目录,指定文件类型为*.txt/*.sh
  2. 将遍历到的文件名和文件路径存到QStringList 再存到QStringListModel
  3. QListView显示Model里面的文件名,item被选中时提取对应文件名的文件路径
  4. .点击打开按钮创建openfileWindow类,传递文件路径过去

openDir.ui
openDir.h

#ifndef OPENDIR_H
#define OPENDIR_H
#include "openfilewindow.h"
#include 
#include 
#include 
#include 
#include 
namespace Ui {class openDir;}
class openDir : public QWidget
{
    Q_OBJECT
public:
    explicit openDir(QWidget *parent = nullptr);
    ~openDir();
    void open_dir(QString temp = NULL);
private slots:
    void on_pushButton_clicked();
    void on_listView_clicked(const QModelIndex &index);
    void on_pushButtonClose_clicked();
    void FuncExit();
private:
    Ui::openDir *ui;
    QStringList fileNameList;//存储文件名
    QStringList filePathList;//存储文件路径
    QStringListModel *model;//QListView存储所需要的容器
signals:
    void UsbDeviceExitByopenDir();
    void DirExit();
};
#endif // OPENDIR_H

openDir.cpp

#include "opendir.h"
#include "ui_opendir.h"

openDir::openDir(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::openDir)
{
    ui->setupUi(this);
    model = new QStringListModel(this);
}
openDir::~openDir()
{
    delete ui;
}

//选择文件夹并且显示在UI上
void openDir::open_dir(QString temp)
{
    QString path;
    if(!temp.isEmpty())
    {
        path = temp;
    }
    else
    {
        qDebug()<<"无USB设备路径...";
        return;
    }
    QDirIterator iter(path, QStringList() << "*.txt" << "*.sh",
                       QDir::Files | QDir::NoSymLinks,
                       QDirIterator::Subdirectories);
    fileNameList.clear();
    filePathList.clear();
    while(iter.hasNext())//遍历QDirIterator
    {
        iter.next();
        fileNameList.append(iter.fileName());
        filePathList.append(iter.filePath());
        model->setStringList(fileNameList);
        ui->listView->setModel(model);
    }
}

//打开选中的文件
void openDir::on_pushButton_clicked()
{
    QString FliePath = ui->textEdit->toPlainText();
    if(!FliePath.isEmpty())
    {
        //打开文件
        openfileWindow *filewindow;
        filewindow = new openfileWindow();
        filewindow->setFilePath(FliePath);
        filewindow->show();
        connect(this,SIGNAL(UsbDeviceExitByopenDir()),filewindow,SLOT(FuncExit()));
    }
}

//实现每次选取item也选取到对应的路径 方便后面的文件 *** 作
void openDir::on_listView_clicked(const QModelIndex &index)
{
    if(fileNameList.contains(index.data().toString()))
    {
        //获取fileNameList的index,filePathList与其相同,因为是同时存的
        int temp =fileNameList.indexOf(index.data().toString());
        ui->textEdit->setText(filePathList.at(temp));
    }
}

//关闭按钮
void openDir::on_pushButtonClose_clicked()
{
    FuncExit();
    emit DirExit();
}

void openDir::FuncExit()
{
    qDebug()<<"openDir::FuncExit()";
    emit UsbDeviceExitByopenDir();
    this->close();
}

3.openfileWindow类
  1. 使用QFile类打开文件路径对应的文件
  2. 将文件内容取出来 显示在UI上后 关闭文件
  3. 点击保存按钮 打开文件 将UI上面的内容存到文件 关闭文件

openfileWindow.ui
openfileWindow.h

#ifndef OPENFILEWINDOW_H
#define OPENFILEWINDOW_H

#include 
#include 
#include 
#include 
namespace Ui {class openfileWindow;}
class openfileWindow : public QWidget
{
    Q_OBJECT
public:
    explicit openfileWindow(QWidget *parent = nullptr);
    ~openfileWindow();
    void setFilePath(QString temp);
private slots:
    void on_pushButtonSave_clicked();
    void on_pushButtonExit_clicked();
    void FuncExit();
private:
    Ui::openfileWindow *ui;
    QString FilePath;
};
#endif // OPENFILEWINDOW_H

openfileWindow.cpp

#include "openfilewindow.h"
#include "ui_openfilewindow.h"
openfileWindow::openfileWindow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::openfileWindow)
{
    ui->setupUi(this);
}
openfileWindow::~openfileWindow()
{
    delete ui;
}

//设置文件路径并且打开文件
void openfileWindow::setFilePath(QString temp)
{
    FilePath = temp;
    if(FilePath.isEmpty() == false)
    {
        QFile file(FilePath);
        bool isok = file.open(QIODevice::ReadOnly);//以只读的方式打开文件
        if(isok == true)
        {
            QByteArray array;
            while(file.atEnd() == false)
            {
                array += file.readLine();//将文件中的读取的内容保存在字节数组中。
            }
            ui->textEdit->setText(array);
        }
        file.close();//文件读取完毕后关闭文件。
    }
}

//保存按钮
void openfileWindow::on_pushButtonSave_clicked()
{
    if(FilePath.isEmpty() == false)
    {
        QFile file(FilePath);
        bool isok = file.open(QIODevice::WriteOnly);
        if(isok == true)
        {
            QString str = ui->textEdit->toPlainText();
            file.write(str.toUtf8());
        }
        file.close();
        this->close();
    }
}

//退出按钮
void openfileWindow::on_pushButtonExit_clicked()
{
    FuncExit();
}
void openfileWindow::FuncExit()
{
    qDebug()<<"openfileWindow::FuncExit()";
    this->close();
}
4.main.cpp
#include "checkusbform.h"
#include 
//打开检测USB设备的窗口--->满足条件打开USB目录窗口--->满足条件打开文件窗口
//检测到USB拔出--->退出文件窗口和USB目录窗口--->回到检测USB设备的窗口
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    CheckUsbForm s;
    s.show();
    return a.exec();
}
总结

检测USB设备的方法是单一的,只是为了实现效果。看其他博主的方法是利用qt自带的QDBus实现一个usb设备管理器,链接如下:

https://blog.csdn.net/weixin_39576127/article/details/111884653

但是我尝试后始终无法收到设备的信号,所以使用了最原始的打开bash,使用[df -hT]分析返回信息来判断。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/2990401.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-09-23
下一篇 2022-09-23

发表评论

登录后才能评论

评论列表(0条)

保存