zoukankan      html  css  js  c++  java
  • Qt SD卡 文件系统挂载、文件预览

    /**********************************************************************************
     *                         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 = 0);
        
            /**
             * 信号通过传参的方式,后续由UI线程dealWithUi()槽统一处;
             */
            static const int PRE_MOUNT       = 1;
            static const int POST_MOUNT      = 2;
            static const int DEVICE_UNEXIST  = 3;
            /**
             * @brief SLEEP_DELAY_MS
             * 设置mount后等待的时间,这里其实可以不需要,但是本人还是设置了,没有原因   :)
             */
            static const int SLEEP_DELAY_MS = 1000;
        
        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 = 0);
            ~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( 20 );
            ui->showDir->setSortingEnabled( true );
            ui->showDir->setColumnWidth( 0, 250 );
        
            /**
             * 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( 0, 0 ) );
        }
        
        void MainWindow::resizeEvent(QResizeEvent *)
        {
            this->showMaximized();
        }
        
        void MainWindow::closeEvent(QCloseEvent *)
        {
            exit(0);
        }
  • 相关阅读:
    无尽的冒险
    推荐一款好用的markdown编辑器,还可以引入vue主题
    你是微光
    Echarts 空心饼图示例
    vue + element-ui 制作tab切换(切换vue组件,踩坑总结)
    vue + element-ui 制作tab切换(适用于单页切换不同标记显示不同内容)
    Element UI 封装Table --> 实现动态创建表头和单元格数据(单元格内可动态增加非纯文本的内容)
    Element UI 封装Table --> 实现动态创建表头和单元格数据(无需写死表头和单元格数据)
    vue 部署到生产出现语法错误和css警告(Resource interpreted as Stylesheet but transferred with MIME type text/html: "www.aaa.com/cal/static/css/app.c06.css". vendor.4b6.js:1 Uncaught SyntaxError: Unexpected token '<')
    使用vue-cookies插件操作cookie
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/4892973.html
Copyright © 2011-2022 走看看