/**********************************************************************************
* Qt SD卡 文件系统挂载、文件预览
* 声明:
* 1. 验证挂载SD卡;
* 2. QTreeView显示文件系统文件;
* 3. UI线程、普通线程通信,以及理解其工作分配;
* 4. static const的使用;
* 5. QString与const char *的转换;
*
* 2015-10-20 晴 深圳 南山平山村 曾剑锋
*********************************************************************************/ \\\\\\\\\\-*- 目录 -*-//////////
| 一、cat main.cpp
| 二、cat mountthread.h
| 三、cat mountthread.cpp
| 四、cat mainwidow.h
| 五、cat mainwindow.cpp
--------------------------------
一、cat main.cpp
#include "mainwindow.h"
#include <QApplication> int main(int argc, char *argv[])
{
QApplication a(argc, argv); /**
* 1. 创建窗口
* 2. 设置标题
* 3. 设置无最大最小化按钮
* 4. 显示窗口
*/
MainWindow w;
w.setWindowTitle("fileSystem");
w.setWindowFlags(w.windowFlags()& ~Qt::WindowMaximizeButtonHint& ~Qt::WindowMinimizeButtonHint);
w.show(); return a.exec();
} 二、cat mountthread.h
#ifndef MOUNTTHREAD_H
#define MOUNTTHREAD_H #include <QThread>
#include <QString>
#include <QMessageBox>
#include <QFileInfo> /**
* @brief The MountThread class
* 挂载文件系统线程,需要创建这个线程的原因如下:
* 1. 当mountSD按钮被按下的时候,需要使按钮处于无效状态;
* 2. 当SD卡文件系统挂载完毕时,按钮要处于有效状态;
* 3. 这么做主要是防止一些误操作,或者也可当作为一种状态提示;
* 4. 基于以上原因,就出现了preMount()、postMount()这两个信号;
* 5. preMount()在处理mount之前发出的信号,UI线程可以更新按钮到无效状态;
* 6. postMout()在处理mount之后发出的信号,UI先生可以更新按钮到有效状态;
*
* 其实之所以要这么做,是因为如果这些在UI线程中做,一般在一个函数里完成,UI线程采用
* 从上到下的程序执行流程,无法更新UI控件的状态,所以目前只能采用这种方式来做。
*/
class MountThread : public QThread
{
Q_OBJECT
public:
/**
* @param exsdNode 扩展sd卡生成的设备节点
* @param mountNode 要将sd卡挂载到那个文件系统节点上
* @param parent
*/
explicit MountThread(QString exsdNode, QString mountNode, QObject *parent = ); /**
* 信号通过传参的方式,后续由UI线程dealWithUi()槽统一处;
*/
static const int PRE_MOUNT = ;
static const int POST_MOUNT = ;
static const int DEVICE_UNEXIST = ;
/**
* @brief SLEEP_DELAY_MS
* 设置mount后等待的时间,这里其实可以不需要,但是本人还是设置了,没有原因 :)
*/
static const int SLEEP_DELAY_MS = ; signals:
void preMount(int mesg);
void postMount(int mesg);
void deviceUnExist(int mesg); private:
/**
* 重写run方法
*/
void run(); private:
/**
* 扩展sd卡生成的设备节点
*/
QString exsdNode;
/**
* 要将sd卡挂载到那个文件系统节点上
*/
QString mountNode;
}; #endif // MOUNTTHREAD_H 三、cat mountthread.cpp
#include "mountthread.h" MountThread::MountThread(QString exsdNode, QString mountNode, QObject *parent) :
QThread(parent)
{
/* 获取sd卡设备节点,mount需要挂载到的文件系统节点 */
this->exsdNode = exsdNode;
this->mountNode = mountNode;
} void MountThread::run()
{
/* 发送开始mount信号 */
emit preMount( PRE_MOUNT ); QFileInfo fileInfo( exsdNode );
if( fileInfo.exists() ) { /**
* 1. 先卸载一下,保证当前次挂载
* 2. 重新挂载在目标文件节点上
* 3. 等待一下,这里貌似可以不等待的,没有理由 :)
*/
system( QString( "umount " ).append( exsdNode ).toLocal8Bit() );
system( QString( "mount " ).append( exsdNode ).append( " " ).append( mountNode ).toLocal8Bit() );
msleep( SLEEP_DELAY_MS ); } else {
/* 设备节点不存在,弹出提示框 */
/* 2015-11-12 modify : move this to UI thread
// QMessageBox::warning(NULL, "WARNING", "Please check your SD card has plugin slot.");
emit deviceUnExist(DEVICE_UNEXIST);
} /* 发送结束mount信号 */
emit postMount( POST_MOUNT );
} 四、cat mainwidow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QMainWindow>
#include <QFileSystemModel>
#include <QThread>
#include <mountthread.h> namespace Ui {
class MainWindow;
} class MainWindow : public QMainWindow
{
Q_OBJECT public:
explicit MainWindow(QWidget *parent = );
~MainWindow(); protected:
void moveEvent(QMoveEvent *);
void resizeEvent(QResizeEvent *);
void closeEvent(QCloseEvent *); private slots:
void on_detectButton_clicked();
void on_umountButton_clicked();
/**
* 处理MountThread线程发送过来的preMount()和postMount()信号
*/
void dealwithUi(int mesg); private:
QFileSystemModel model;
Ui::MainWindow *ui;
MountThread *mountThread; // 挂载线程
}; #endif // MAINWINDOW_H 五、cat mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <QFileInfo>
#include <QMessageBox>
#include <QTreeView>
#include <QDebug> /* sd卡生成的设备节点 */
#define EXSD_NODE "/dev/mmcblk1p1"
/* sd卡挂载的文件系统节点 */
#define MOUNT_NODE "/mnt/exsd" MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{ ui->setupUi(this); /**
* 这里主要是设置treeview的一些参数
*/
ui->showDir->setModel( &model );
model.setRootPath( MOUNT_NODE );
ui->showDir->setRootIndex( model.index( MOUNT_NODE ) ); // Demonstrating look and feel features
ui->showDir->setAnimated( false );
ui->showDir->setIndentation( );
ui->showDir->setSortingEnabled( true );
ui->showDir->setColumnWidth( , ); /**
* 1. 创先mount线程;
* 2. 绑定信号与槽。
*/
mountThread = new MountThread( EXSD_NODE, MOUNT_NODE );
connect( mountThread, SIGNAL(preMount(int)), this, SLOT(dealwithUi(int)) );
connect( mountThread, SIGNAL(postMount(int)), this, SLOT(dealwithUi(int)) ); } void MainWindow::dealwithUi(int mesg)
{
if( MountThread::PRE_MOUNT == mesg ) { /* 将button设置为无效效果 */
ui->detectButton->setEnabled( false );
ui->umountButton->setEnabled( false ); qDebug() << "premount." << endl; } else if ( MountThread::POST_MOUNT == mesg ) { /**
* 1. 这里一定需要:
* model.setRootPath( "/mnt" );
* model.setRootPath( MOUNT_NODE );
* 2. /mnt不是固定的,随便什么值都行,这里主要是为了触发rootPath改变了,在设置回来,
* 要不然,treeview不会显示。
*/
model.setRootPath( "/mnt" );
model.setRootPath( MOUNT_NODE );
ui->showDir->setRootIndex( model.index( MOUNT_NODE ) ); /* 恢复按钮有效效果 */
ui->detectButton->setEnabled( true );
ui->umountButton->setEnabled( true ); qDebug() << "postmount." << endl; /* 2015-11-12 add this for in UI thread */
} else if ( MountThread::DEVICE_UNEXIST == mesg ) {
QMessageBox::warning(NULL, "WARNING", "Please check your SD card has plugin slot.");
}
} void MainWindow::on_detectButton_clicked()
{
/**
* 1. 开启线程,看似无关紧要的,只有短短一行,却包暗含着UI线程与普通线程的区别;
* 2. UI线程维护UI界面的更新;
* 3. UI界面不宜做时间很长、耗费资源的事;
* 4. 普通线程通过发送信号与UI线程进行沟通,处理UI显示更新。
*/
mountThread->start();
} void MainWindow::on_umountButton_clicked()
{
/* 卸载sd卡 */
system( QString( "umount " ).append( EXSD_NODE ).toLocal8Bit() );
} MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::moveEvent(QMoveEvent *)
{
this->move( QPoint( , ) );
} void MainWindow::resizeEvent(QResizeEvent *)
{
this->showMaximized();
} void MainWindow::closeEvent(QCloseEvent *)
{
exit();
}

Qt SD卡 文件系统挂载、文件预览的更多相关文章

  1. 与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件

    [源码下载] 与众不同 windows phone (37) - 8.0 文件系统: StorageFolder, StorageFile, 通过 Uri 引用文件, 获取 SD 卡中的文件 作者:w ...

  2. Android Environment 判断sd卡是否挂载 获取sd卡目录

    在将一个文件存储到sd卡上面的时候,一般需要判断sd是否已经挂载才进行操作. 那么如何判断sd卡已经挂载呢? 我们可以使用Android的Environment类,具体使用如下: if(Environ ...

  3. Android 5.1.1在外置SD卡中创建文件夹

    Android 4.4之后WRITE_MEDIA_STORAGE 权限仅提供给系统应用,不再授予第三方App,WRITE_EXTERNAL_STORAGE 权限,仅仅用于授权用户写 primary e ...

  4. Android开发之SDCardUtils工具类。java工具详细代码,附源代码。判断SD卡是否挂载等功能

    package com.xiaobing.zhbj.utils; import java.io.BufferedInputStream; import java.io.BufferedOutputSt ...

  5. 【记录】尝试用android-logging-log4j去实现log输出内容到sd卡中的文件的功能

    [背景] 折腾: [记录]给Android中添加log日志输出到文件 期间,已经试了: [记录]尝试用android中microlog4android实现log输出到文件的功能 但是不好用. 然后就是 ...

  6. android学习笔记47——读写SD卡上的文件

    读写SD卡上的文件 通过Context的openFileInput.openFileOutput来打开文件输入流.输出流时,程序打开的都是应用程序的数据文件夹里的文件,其存储的文件大小可能都比较有限- ...

  7. java实现office文件预览

    不知觉就过了这个久了,继上篇java实现文件上传下载后,今天给大家分享一篇java实现的对office文件预览功能. 相信大家在平常的项目中会遇到需要对文件实现预览功能,这里不用下载节省很多事.大家请 ...

  8. android 操作SD卡上的文件

    (1)说明:操作SD卡上的文件须要增加下面权限  在SD卡上创建和删除文件权限  <uses-permission android:name="android.permission.M ...

  9. Jquery.Treeview+Jquery UI制作Web文件预览

    效果图: 前台Html: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="D ...

随机推荐

  1. Ubuntu下virtualenv 的安装及使用

    按照这个命令做下来基本是ok的. https://blog.csdn.net/qq_33371343/article/details/78047853

  2. 查准率与查全率(precision and recall) 的个人理解

    假设要识别照片中的狗的,在一些照片中,包含12只狗的照片和一些猫的照片.算法识别出有8只狗.在确定的8只狗中,5只实际上是狗(真阳性TP),而其余的是猫(假阳性FP).该程序的精度为5/8,而其召回率 ...

  3. 26QTimer定时器的使用

    前面介绍过定时器事件(QTimerEvent),有个弊端,就是每启动一个定时器都要对应的ID.本次介绍在设计器中使用Qtimer. 首先在设计器中添加一个LCD Number,和两个按钮. 头文件 # ...

  4. Qt的信号和槽是如何工作的

    用Qt做过开发的朋友,不知道是否曾为下面这些问题疑惑过:我们知道Qt是基于C++的,Qt写的代码最终还是要由C++编译器来编译,但是我们的Qt代码中有很多C++里没有的关键字,比如slots\sign ...

  5. Centos75下samba搭建配置

    工作中,很经常需要把Linux服务器上的文件共享到windows上面,这时候需要在Linux服务器上安装samba套件. samba服务很好的实现了windows和linux之间的文件共享. 下面配置 ...

  6. hdu_2048 错排问题

    错排问题本质上就是一个动态规划问题,其状态转移方程为: 记d[n]为n个人错排情况的总数. 那么策略可以描述为:分析第n个人错排的可能情况: 1)前n-1个人满足错排的情况,那么第n个人加入后还要错排 ...

  7. godaddy之ssl申请

    第一步 执行下面命令生成csr和key文件 openssl req -new -newkey rsa: -nodes -keyout trips.com.key -out trips.com.csr ...

  8. 【异常记录(七)】MVC:从客户端中检测到有潜在危险的 Request.Form 值 的解决方法 [转]

    从客户端(Content="<EM ><STRONG ><U >这是测试这...")中检测到有潜在危险的Request.Form 值. 说明:  ...

  9. HDU 3315 My Brute(二分图最佳匹配+尽量保持原先匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=3315 题意: 有S1到Sn这n个勇士要和X1到Xn这n个勇士决斗,初始时,Si的决斗对象是Xi. 如果Si赢了X ...

  10. pairs 和 ipairs 的区别

    ipairs 在迭代过程中是会直接跳过所有手动设定key值的变量.pairs不会跳过手动设置key值的变量. 实例 tab = {,,a="cd","d"} f ...