- 使用QProcess类打开外部程序并与之交互通信。
- 使用QDirIterator类浏览目录内容并且显示在QListView内。
- 使用QFlie类读写文件。
- 检测USB设备是否插入,插入后可进入USB目录内的文本文件(.txt/.sh)并且显示在界面上。
- 选择界面上显示的文件可以打开查看和修改内容。
- 拔出USB会回到初始界面。
- 创建一个bash进程
- 每秒给bash发送[df -hT]根据返回值检测是否存在sdb设备,存在的话Enable按钮
- 点击PushButton创建openDir类,传递sdb的路径给openDir
- 接收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类
- 使用QDirIterator遍历sdb路径的目录,指定文件类型为*.txt/*.sh
- 将遍历到的文件名和文件路径存到QStringList 再存到QStringListModel
- QListView显示Model里面的文件名,item被选中时提取对应文件名的文件路径
- .点击打开按钮创建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类
- 使用QFile类打开文件路径对应的文件
- 将文件内容取出来 显示在UI上后 关闭文件
- 点击保存按钮 打开文件 将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]分析返回信息来判断。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)