2013年1月18日金曜日

( Qt C++ )ディレクトリ内の全てのファイル・ディレクトリ名を取得する


表題の件やっていきます。

早速コードを

   #include <QDir> 
   QDir q_dir("C:/MinGW");

    if(q_dir.exists())
        QStringList filelist = q_dir.entryList();//C:/MinGW内の全てのファイル・ディレクトリ名取得

簡単ですね。今回は指定していませんが引数にQDir::Filter, QDir::SortFlagsをセットすると、フォルダのみでサイズ順で取得といったことが可能となります。
フィルタ類に関してはまた次回。

以上。

2013年1月17日木曜日

( Qt C++ )ディレクトリが存在するか調べる


今日からディレクトリ関連の記事を書いていこうと思います。
では早速コードを
    
    #include <QDir>
    QDir q_dir("C:/MinGW");//対象ディレクトリをセット

    if(q_dir.exists())//そのディレクトリがあるならtrue。ないならfalse。
    {
        //ディレクトリがあった場合の処理
    }


以上です。処理についてはコメントのとおりです。
QDirクラスはディレクトリ構造と内容へのアクセスを提供するクラスです。
 コンストラクタで対象ディレクトリのパスをセットします。パスのセットはコンストラクタ以外でもできますが、パスがわかっているならコンストラクタで指定してしまったほうが楽です。

また、区切り文字は円マークとかではなく、"/"で区切ったほうがいいようです。"/"で区切った場合、自動で各OSに合った区切り文字に変換してくれます。 また、例では絶対パスで指定していますが、相対パスでもいいようです。
以上。

2013年1月16日水曜日

(Sample)Qt C++でリネームソフトを作る 第4回 実装


はいそれでは実装をやっていきます。

簡単な説明のみです。詳細についてはfreesoftページにアップロードしたプロジェクトを参照してください。1000行以下なので簡単に読めるはずです。

ではおおまかな説明を

(mainwindow.h)

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMessageBox>
#include <QFileDialog>
#include <QFileInfo>
#include <QDateTime>
#include <QtGlobal>
#include <QTreeWidgetItem>
#include <QFileIconProvider>
#include <QTextCodec>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private slots:
    void on_FolderDialog_triggered();

    void on_FormClose_triggered();

    void on_Run_triggered();

    void on_NameSort_triggered();

    void on_TimeSort_triggered();

    void on_SizeSort_triggered();

    void on_ExtentionSort_triggered();

private:
    Ui::MainWindow *ui;
    QDir::SortFlags m_SortFlag;//ソートの種類
    QString m_FolderPath;//読込フォルダのパス
    QStringList m_FileNameList;//ファイル名のリスト。表示に使用する。
    QStringList m_AbsolutePathList;//ファイルの絶対パスリスト
    void GetFiles(QString path, QDir::SortFlags sort);//ファイルを取得・編集する
    void InitTree(QString dir, QStringList list);//ツリービューの初期化
    void ShowMessage(QString m);//メッセージボックス関数
    bool ShowYesNoMessage(QString m);//yes,noボタンのメッセージボックス
    void ClearCheck();//ソートのチェックを全てクリアする
};

#endif // MAINWINDOW_H

ヘッダは以上です。コメントのとおりです。


 (mainwindow.cpp)
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_SortFlag = QDir::Name;
    ui->NameSort->setChecked(true);
}

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

//フォルダ選択クリック
void MainWindow::on_FolderDialog_triggered()
{
    QFileDialog file_dialog(this);
    file_dialog.setFileMode(QFileDialog::Directory);//フォルダ選択ダイアログ

    if (file_dialog.exec())
    {
        GetFiles(file_dialog.selectedFiles()[0], m_SortFlag);
        InitTree(m_FolderPath, m_AbsolutePathList);
    }
}

//終了クリック
void MainWindow::on_FormClose_triggered()
{
    this->close();
}

//実行クリック
void MainWindow::on_Run_triggered()
{
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");//文字化け対策
    if(m_AbsolutePathList.length() <= 0 || ShowYesNoMessage(codec->toUnicode("実行してもよいか?")) == false) return;

    QString error_files = QString::null;//リネームに失敗したファイル名を格納していく
    int count = ui->spinBox->value();//リネーム時に付加する開始番号。
    for(int i = 0; i < m_AbsolutePathList.length(); i++)
    {
        QFileInfo file_info(m_AbsolutePathList[i]);
        QFile file(m_AbsolutePathList[i]);
        QString ext = file_info.completeSuffix();//拡張子の文字列取得

        if(file.exists() == false)//対象のファイルがあるのかどうか
        {
            ShowMessage("File Not Exist!!\nNot Completed!\n\n<Detail>\n" + m_AbsolutePathList[i]);
            return;
        }

        if(ext.count() > 0)//拡張子ありなら
        {
            if(!QFile::rename(file.fileName(), m_FolderPath + "/"+ ui->baseLineEdit->text() + QString::number((count + i)) + "." +  ext))
                error_files += m_AbsolutePathList[i] + "\n\n";
        }
        else//拡張子なしなら
        {
            if(!QFile::rename(file.fileName(), m_FolderPath + "/"+ ui->baseLineEdit->text() + QString::number((count + i))))
                error_files += m_AbsolutePathList[i] + "\n\n";
        }
    }

    GetFiles(m_FolderPath, m_SortFlag);
    InitTree(m_FolderPath, m_AbsolutePathList);

    if(error_files != QString::null)
    {
        QMessageBox msg;
        msg.setWindowTitle("Error!");
        msg.setText("Error! Can't rename there files");
        msg.setDetailedText(error_files);
        msg.exec();
    }

    ShowMessage("Completed!!");
}

//ファイルの取得・編集
void MainWindow::GetFiles(QString path, QDir::SortFlags sort)
{
    m_FolderPath = path;
    QDir dir(m_FolderPath);//フォルダの絶対パスをセットする
    if(m_FolderPath.length() == 0 || !dir.exists()) return;

    m_FileNameList.clear();
    m_AbsolutePathList.clear();

    m_FileNameList = dir.entryList(QDir::Files, sort);//フォルダ内のファイルをソートして全て取得

    foreach(QString str, m_FileNameList)
    {
        m_AbsolutePathList << dir.path() + "/" + str;
    }
}

//ツリービュー初期化
void MainWindow::InitTree(QString dir, QStringList list)
{
    ui->treeWidget->clear();

    QTreeWidgetItem *base_item = new QTreeWidgetItem;
    base_item->setText(0, dir);
    QFileIconProvider icon_pro;
    base_item->setIcon(0, icon_pro.icon(QFileIconProvider::Folder));//システムのフォルダアイコンを取得

    for(int i = 0; i < list.length(); i++)
    {
        QTreeWidgetItem *item = new QTreeWidgetItem;
        QFileInfo file_info(list[i]);
        item->setText(0, file_info.fileName());//ファイル名
        item->setText(1, QString("%1byte").arg(file_info.size()));//バイト数
        item->setText(2, file_info.lastModified().toString() + "(last)");//更新日
        item->setIcon(0,  icon_pro.icon(QFileIconProvider::File));//アイコン
        base_item->addChild(item);
    }

    ui->treeWidget->insertTopLevelItem(0, base_item);
    ui->treeWidget->expandAll();//ツリービューを開いた状態にする
}

//通常のメッセージボックスを表示
void MainWindow::ShowMessage(QString m)
{
    QMessageBox msgBox;
    msgBox.setText(m);
    msgBox.exec();
}

//Yes,Noのボタンのついたメッセージボックスを表示
bool MainWindow::ShowYesNoMessage(QString m)
{
    QMessageBox msg_box;
    msg_box.setText(m);
    msg_box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msg_box.setDefaultButton(QMessageBox::Yes);

    int ret = msg_box.exec();

    switch(ret)
    {
    case QMessageBox::Yes:
        return true;
        break;
    case QMessageBox::No:
        return false;
        break;
    }

    return false;
}

//ソートのチェック状態をクリアする
void MainWindow::ClearCheck()
{
    ui->NameSort->setChecked(false);
    ui->TimeSort->setChecked(false);
    ui->SizeSort->setChecked(false);
    ui->ExtentionSort->setChecked(false);
}

//ソートの名前順クリック
void MainWindow::on_NameSort_triggered()
{
    ClearCheck();
    ui->NameSort->setChecked(true);
    m_SortFlag = QDir::Name;
    if(m_FolderPath.length() == 0) return;
    GetFiles(m_FolderPath, m_SortFlag);
    InitTree(m_FolderPath, m_AbsolutePathList);
}

//ソートの時間順クリック
void MainWindow::on_TimeSort_triggered()
{
    ClearCheck();
    ui->TimeSort->setChecked(true);
    m_SortFlag = QDir::Time;
    if(m_FolderPath.length() == 0) return;
    GetFiles(m_FolderPath, m_SortFlag);
    InitTree(m_FolderPath, m_AbsolutePathList);
}

//ソートのサイズ順クリック
void MainWindow::on_SizeSort_triggered()
{
    ClearCheck();
    ui->SizeSort->setChecked(true);
    m_SortFlag = QDir::Size;
    if(m_FolderPath.length() == 0) return;
    GetFiles(m_FolderPath, m_SortFlag);
    InitTree(m_FolderPath, m_AbsolutePathList);
}

//ソートの拡張子順クリック
void MainWindow::on_ExtentionSort_triggered()
{
    ClearCheck();
    ui->ExtentionSort->setChecked(true);
    m_SortFlag = QDir::Type;
    if(m_FolderPath.length() == 0) return;
    GetFiles(m_FolderPath, m_SortFlag);
    InitTree(m_FolderPath, m_AbsolutePathList);
}


これも見てのとおりです。コンストラクタ、デストラクタは見たまんまですので説明を省きます。

フォルダの選択ではQFileDialogを使います。Fileと書かれていますが、setFileModeでQFileDialog::Directoryを事前にセットすることでフォルダダイアログとなります。

終了も説明を省きます。closeするだけです。

実行はコメントのとおりです。特別な処理はありません。

ソートは今回はひとつしかチェックできないようにしておりますが、複数セットすることが可能のようです。
あとは見てのとおりです。

実行すると以下のようになります。






以上です。