hakeの日記

Windows環境でプログラミングの勉強をしています。

C++でQTアプリ(その4) ファイルの選択

ディレクトリを移動してファイルを選択する。下のプログラムではカレントディレクトリの内容をQListViewにリストを表示する。リスト中ディレクトリを選択した場合はディレクトリ移動を行って、その内容をリスト表示。
ディレクトリ関係の処理はQDirクラスを使用。更にQdir.entryInfoList()とQFileInfoListおよびQFileInfoListIteratorを用いることでディレクトリ下の各要素各々に対して処理を行うことが可能、RubyのDir.each{|file| … }と同じ感じ。関数makeFileList()は、リファレンスの例題をそのまま使用した。

        const QFileInfoList *list = d.entryInfoList();
        QFileInfoListIterator it( *list );      // リストイテレータの作成
        QFileInfo *fi;                          // 走査を行うポインタ
        while ( (fi=it.current()) ) {           // 各ファイルに対し...
            処理
            ++it;                               // リストの次の要素へ進む
        }

ファイル名についてはQStringを用いているせいかUTF-8な日本語でも問題なく処理してくれた。
QDir.setSortingの設定はQListView側で勝手にソートしてしまうので意味を成さない。QListView側でもう一つカラムを追加してQListView.insertItem毎にインクリメントする数値を設定していけば良いと思う。


filelist.h
#ifndef FILELIST_H
#define FILELIST_H

#include <qmainwindow.h>
#include <qtextcodec.h>
#include <qfont.h>
#include <qvbox.h>
#include <qlineedit.h>
#include <qlistview.h>
#include <qstring.h>
#include <qdir.h>
#include <qfileinfo.h>
#include <qregexp.h>


class FileList : public QMainWindow{
	Q_OBJECT

public:
	FileList(QWidget *parent = 0, const char *name = 0);
//	~FileList();

private:
	QVBox *v;

	QLineEdit *eb0;
	QListView *list;
	QLineEdit *eb1;
	QDir curDir;
//	QRegExp regSlash;

private:
	void makeFileList( QDir );

private slots:
	void slot_fileList( QListViewItem * );
};

#endif
filelist.cpp
#include "filelist.h"

FileList::FileList(QWidget *parent, const char *name)
		: QMainWindow(parent, name)
{
	setCaption("File List");
	QFont f("lcfont",18);
	setFont(f);              // Widget内のフォント設定

	v = new QVBox( this );
	setCentralWidget(v);

	eb0 = new QLineEdit( v );   // カレントパス表示
	eb0->clear();
	eb0->setFocusPolicy( QWidget::NoFocus );
	eb0->setReadOnly( true );

	list = new QListView( v );  // Fileリスト表示
	list->addColumn("List");
	list->clear();

	eb1 = new QLineEdit(v);
	eb1->clear();
	eb1->setFocusPolicy( QWidget::NoFocus );
	eb1->setReadOnly( true );

	QDir curDir;
	curDir.setPath( "/home/zaurus" ); // 初期カレントディレクトリ
	makeFileList( curDir );
	

	// タップ&Enterした場合、選択されたQListViewItemをスロットへ渡す
	connect( list, SIGNAL(clicked( QListViewItem * )),
		this, SLOT(slot_fileList( QListViewItem * )) );
	connect( list, SIGNAL(returnPressed( QListViewItem * )),
		this, SLOT(slot_fileList( QListViewItem * )) );
}


// list中のアイテムを選択した場合
void FileList::slot_fileList( QListViewItem *item )
{
	if(!item) return;  // 非アイテム部分をタップした場合
	
	QRegExp regSlash( "/$" ); // 末尾のスラッシュにマッチ
	// コンストラクタで宣言すると使用不可?

	QString str = "File : ";
	QString file = item->text(0);
	uint len = 0;
	if( regSlash.match( file, 0 ) != -1){ // 名前の最期にスラッシュがある場合
		len = file.length();
		file = file.left( len - 1 );      // Dir名取得、スラッシュ除去
		curDir.cd( file );                // Dir移動
		makeFileList( curDir );
		str = "cd ";
		str += curDir.absPath();
		eb1->setText( str );
	}else{                                // fileの場合
		str += file;
		eb1->setText( str );
	}
}


// ディレクトリの要素をlistに表示
void FileList::makeFileList( QDir d)
{
	QDir dir = d;
	dir.setFilter( QDir::Dirs | QDir::Files | QDir::Hidden ); // 隠しファイルも表示
	dir.setSorting( QDir::DirsFirst | QDir::Name ); // ソート順、今回は意味がない
	list->clear();
	eb0->setText( dir.absPath() ); //カレントパス表示
	eb1->clear();

	QString filename = "";
	const QFileInfoList *filist = dir.entryInfoList(); // constが必要
	QFileInfoListIterator it( *filist );
	QFileInfo *fi;
	// 各要素をlistに追加、Dirの場合はスラッシュ付加
	while(( fi = it.current() )){   // 括弧の数がこれだけ必要
		filename = fi->fileName();  // 名前取得
		if( fi->isDir() ) filename += "/";
		QListViewItem *item = new QListViewItem( list, filename );
		list->insertItem( item );   // listに追加
		++it;  // ++はitの前でないといけない
	}
}