Qt之課外實踐——檔案操作(簡單清道夫)

[0]發表於2015-01-02

說明:這個小專案是關於檔案操作的。主要的功能有:重複檔案的查詢(根據檔案的大小),說白了,就是講大小相同的檔案在一起顯示出來,供使用者自由的選擇刪除。這個360雲盤裡的檔案去重還差的很遠。還有空資料夾的查詢(我們的思想是:如果一個目錄下面只有.和..2個目錄,則,這個資料夾就是空的。但是我們不包含檔案裡面套有空資料夾。),以及垃圾檔案的查詢(根據檔案的字尾,簡單判斷的。)。

窗體主介面:

image

首先程式執行前,會彈出提示對話方塊。

image

程式碼如下:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QLabel>
#include <QList>
#include <QMainWindow>
#include <QModelIndex>
#include <QMultiHash>
#include <QStandardItemModel>
class QTableView;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QString FunGetPath();//得到資料夾路徑
    void FunClear();//清空函式
    void initStatustBar();//初始化狀態列
    void setStarStatust();//設定開始狀態列
    void setEndStatust();//設定結束狀態列
private:
    Ui::MainWindow *ui;
    QTableView *tableView;
    QStandardItemModel *model;
    QMultiHash<int,QString> mH;
    QList<int> fileSize;
    QLabel *firstStatust;

public slots:
    void duplicateFile();//重複檔案
    void emptyFile();//空檔案
    void junkFile();//垃圾檔案
    void slotDelFile();//刪除檔案
    void delAllFile();//全部刪除
};

#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.resize(800,500);
    w.show();    
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QAction>
#include <QDebug>
#include <QDir>
#include <QDirIterator>
#include <QFileDialog>
#include <QFileInfo>
#include <QItemSelectionModel>
#include <QGridLayout>
#include <QMap>
#include <QMessageBox>
#include <QModelIndex>
#include <QStandardItemModel>
#include <QStatusBar>
#include <QTableView>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    tableView = new QTableView(ui->centralWidget);
    QGridLayout *layout = new QGridLayout();
    layout->addWidget(tableView);
    ui->centralWidget->setLayout(layout);

    //新增工具欄
    QAction *hashFile = new QAction(tr("重複檔案清理"),ui->mainToolBar);
    QAction *emptyFile = new QAction(tr("空資料夾清理"),ui->mainToolBar);
    QAction *junkFile = new QAction(tr("垃圾檔案清理"),ui->mainToolBar);
    QAction *delFile = new QAction(tr("檔案刪除"),ui->mainToolBar);
    QAction *delAllFile = new QAction(tr("全部刪除"),ui->mainToolBar);

    ui->mainToolBar->addAction(hashFile);
    ui->mainToolBar->addAction(emptyFile);
    ui->mainToolBar->addAction(junkFile);
    ui->mainToolBar->addSeparator();
    ui->mainToolBar->addAction(delFile);
    ui->mainToolBar->addAction(delAllFile);

    connect(hashFile,SIGNAL(triggered()),this,SLOT(duplicateFile()));//檔案去重
    connect(emptyFile,SIGNAL(triggered()),this,SLOT(emptyFile()));//空資料夾
    connect(junkFile,SIGNAL(triggered()),this,SLOT(junkFile()));//垃圾檔案

    connect(delFile,SIGNAL(triggered()),this,SLOT(slotDelFile()));//單、多檔案刪除
    connect(delAllFile,SIGNAL(triggered()),this,SLOT(delAllFile()));//全部刪除
    //準備資料模型
    model = new QStandardItemModel();
    model->setHorizontalHeaderItem(0,new QStandardItem(QObject::tr("檔名")));
    model->setHorizontalHeaderItem(1,new QStandardItem(QObject::tr("所在位置")));
    model->setHorizontalHeaderItem(2,new QStandardItem(QObject::tr("大小(位元組)")));
    model->sort(2,Qt::DescendingOrder);//感覺沒用上
    tableView->setModel(model);
    //設定表格屬性
    tableView->setColumnWidth(0,150);
    tableView->setColumnWidth(1,550);
    tableView->setColumnWidth(2,70);
    //設定選中為整行選中
    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    //設定表格單元格為只讀
    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);

    QMessageBox::warning(this,tr("警告"),
                         tr("非計算機專業人士,請在計算機專業人士陪同的情況下,使用此軟體。請做到三思而後刪!"),
                         QMessageBox::Yes);

    this->initStatustBar();
}

MainWindow::~MainWindow()
{
    delete ui;
}
//獲取資料夾的路徑
QString MainWindow::FunGetPath()
{
    QString path=QFileDialog::getExistingDirectory(NULL, tr("選擇資料夾"),"D:\\",QFileDialog::ShowDirsOnly);
    bool biag = true;
    //判斷路徑是否存在
    while(biag)
    {
        if(path.isEmpty())
        {
            if(QMessageBox::Yes == QMessageBox::warning(this,tr("警告"),tr("選擇的資料夾路徑不存在,請重新選擇有效的資料夾。"),QMessageBox::Yes))
            {
                path=QFileDialog::getExistingDirectory(NULL, tr("選擇資料夾"),"D:\\",QFileDialog::ShowDirsOnly);
            }
        }
        else
        {
            biag = false;
        }
    }
    return path;
}

//清空函式
void MainWindow::FunClear()
{
    //3個清空操作
    mH.clear();
    fileSize.clear();
    model->removeRows(0,model->rowCount());
}
//初始化狀態列
void MainWindow::initStatustBar()
{
    QStatusBar *bar = ui->statusBar; //獲取狀態列
    firstStatust = new QLabel; //新建標籤
    firstStatust->setMinimumSize(150,20); //設定標籤最小尺寸
    bar->addWidget(firstStatust);
    firstStatust->setText(tr("歡迎使用檔案一掃光!")); //初始化內容
}
//設定開始狀態列
void MainWindow::setStarStatust()
{
    firstStatust->setText(tr("<font color=red>檔案掃描中……</font>"));
}
//設定結束狀態列
void MainWindow::setEndStatust()
{
    firstStatust->setText(tr("<font color=Blue>檔案掃描完畢。</font>"));
}

//重複檔案
void MainWindow::duplicateFile()
{
    this->FunClear();
    this->setStarStatust();//這2句換下位置就不行了
    QString path = this->FunGetPath();
    QDir dir(path);
    if(!dir.exists())
    {
        QMessageBox::warning(this,tr("警告"),tr("選擇的資料夾路徑不存在,請重新選擇有效的資料夾。"),QMessageBox::Yes);
        return;
    }
    //定義迭代器並設定過濾器
    QDirIterator dir_iterator(path,
                              QDir::Files | QDir::NoSymLinks,
                              QDirIterator::Subdirectories);
    int num=0;
    while(dir_iterator.hasNext())
    {
        dir_iterator.next();
        QFileInfo file_info = dir_iterator.fileInfo();
        if(file_info.isFile())
        {
            //qDebug()<<num++<<"-----"<<file_info.absoluteFilePath();
            if(!fileSize.contains(file_info.size()))
            {
                fileSize.append(file_info.size());
            }
            mH.insertMulti(file_info.size(),file_info.absoluteFilePath());
        }
    }
    //qDebug()<<"over......";
    //qSort(fileSize.begin(),fileSize.end(),qGreater<int>());
    QMultiHash<int,QString>::iterator i;
    int jRows = 0;
    for(i=mH.begin();i!=mH.end();i++)
    {
        if(mH.count(i.key())>1)
        {
            //qDebug()<<jRows<<"----------"<<i.key()<<"------"<<i.value();
            QFileInfo fileInfo = QFileInfo(i.value());
            model->setItem(jRows,0,new QStandardItem(fileInfo.fileName()));
            model->setItem(jRows,1,new QStandardItem(i.value()));
            model->setItem(jRows,2,new QStandardItem(QString::number(i.key())));
            jRows++;
        }
    }
    this->setEndStatust();
}

//空資料夾清理
void MainWindow::emptyFile()
{
    this->FunClear();
    this->setStarStatust();

    QString path = this->FunGetPath();
    //判斷路徑是否存在
    QDir dir(path);
    if(!dir.exists())
    {
        QMessageBox::warning(this,tr("警告"),tr("選擇的資料夾路徑不存在,請重新選擇有效的資料夾。"),QMessageBox::Yes);
        return;
    }
    //定義迭代器並設定過濾器
    QDirIterator dir_iterator(path,QDirIterator::Subdirectories);
    int jRows = 0;

    while(dir_iterator.hasNext())
    {
        dir_iterator.next();

        QString filePath = dir_iterator.filePath();
        QString fileName = dir_iterator.fileName();

        QDir dir(filePath);
        if(dir.count() == 2)//檔案==0
        {
            model->setItem(jRows,0,new QStandardItem(fileName));
            model->setItem(jRows,1,new QStandardItem(filePath));
            jRows++;
            dir_iterator.next();//跳過/.目錄
            //dir.rmdir(".");
        }
    }
    this->setEndStatust();
}

//垃圾檔案操作
void MainWindow::junkFile()
{
    this->FunClear();
    this->setStarStatust();

    QString path=this->FunGetPath();
    //判斷路徑是否存在
    QDir dir(path);
    if(!dir.exists())
    {
        QMessageBox::warning(this,tr("警告"),tr("選擇的資料夾路徑不存在,請重新選擇有效的資料夾。"),QMessageBox::Yes);
        return;
    }
    //獲取所選檔案型別過濾器
    QStringList filters;
    filters<<"*.tmp"<<"*._mp"<<"*.log"<<"*.gid"<<"*.chk"<<"*.old";
    //定義迭代器並設定過濾器
    QDirIterator dir_iterator(path,
                              filters,
                              QDir::Files | QDir::NoSymLinks,
                              QDirIterator::Subdirectories);
    int jRows = 0;
    while(dir_iterator.hasNext())
    {
        dir_iterator.next();
        QFileInfo file_info = dir_iterator.fileInfo();
        model->setItem(jRows,0,new QStandardItem(file_info.fileName()));
        model->setItem(jRows,1,new QStandardItem(file_info.filePath()));
        model->setItem(jRows,2,new QStandardItem(QString::number(file_info.size())));
        jRows++;
    }
    this->setEndStatust();
}

// 單個/多個 刪除操作
void MainWindow::slotDelFile()
{
    QItemSelectionModel *selections = tableView->selectionModel();
    QModelIndexList selected = selections->selectedRows();
    if(selected.size()>0)
    {
        for (int i=0; i < selected.size(); i++)
        {
            int index = selected.at(i).row()-i;//因為model是動態變化的
            QFile file(model->item(index,1)->text());
            QFileInfo fileInfo(file);
            QDir dir(fileInfo.filePath());
            if(fileInfo.isDir())//如果是目錄
            {
                //qDebug()<<dir.absolutePath();
                dir.rmdir(".");//刪除空檔案目錄
            }
            else
            {
                if(file.exists())
                {
                    //qDebug()<<model->item(index,1)->text();
                    file.remove();//刪除檔案(重複和垃圾)
                }
            }
            //qDebug()<<model->item(index,1)->text();
            model->removeRow(index);
        }
    }
    else
    {
        QMessageBox::warning(this,tr("警告"),tr("請先進行檔案型別的處理選擇,然後在表格裡選擇要刪除的檔案"),QMessageBox::Yes);
    }    
}

//全部刪除
void MainWindow::delAllFile()
{
    //qDebug()<<model->rowCount();
    if(model->rowCount()>0)
    {
        //設定全選
        QItemSelectionModel *selectionsModel = tableView->selectionModel();
        QModelIndex topLeft = model->index(0,0,QModelIndex());
        QModelIndex bottomRight = model->index(model->rowCount()-1,2,QModelIndex());
        QItemSelection selection(topLeft,bottomRight);
        selectionsModel->select(selection,QItemSelectionModel::Select);

        if(QMessageBox::Yes == QMessageBox::question(this,tr("提問"),tr("您確定要刪除下面所有的檔案嗎?Yes 確定,No 取消"),QMessageBox::Yes,QMessageBox::No))
        {
            this->slotDelFile();//呼叫 單個/多個 刪除函式
            //qDebug()<<"Del...OK!";
        }
    }
    else
    {
        QMessageBox::warning(this,tr("警告"),tr("請先進行檔案型別的處理選擇,然後在表格裡選擇要刪除的檔案"),QMessageBox::Yes);
    }
}

備註:以上這個程式還有很多的不足之處,貼出來,是因為裡面有些Qt的知識還是可以借鑑學習的。

相關文章