読者です 読者をやめる 読者になる 読者になる

日記

ただの日記

QFileSystemModelを見る(QML)

Qtのモジュールはドキュメントがしっかりしてるけど、
使うとなるといまいちどうやって使えばいいのかわからない……

いちいち日本語にまとめるのは時間がかかりすぎるんだけど
勉強し始めということで、ファイルを扱う"QFileSystemModel"についてだけとりあえず見ていく。

QMLとC++の連携がいまいちわからないから、これを通して学びたいところ。

基本

QFileSystemModelはこのクラスを基底として継承し拡張したクラスを用いることがほとんどあるが、継承せずとも使用することはできる。

main関数内でこのように書く。これメモリ解放してないけどいいんだろうか。QMLのTreeViewでファイル一覧を読み込むために必要なオブジェクトはここで渡す。

//QML側でfilesystemmodelという名前でQFileSystemModelを読み込めるようにバージョン1.0として登録
qmlRegisterUncreatableType<QFileSystemModel>("filesystemmodel", 1, 0,
           "FileSystemModel", "Cannot create a FileSystemModel instance.");
//オブジェクト生成
QFileSystemModel *model = new QFileSystemModel();
//ディレクトリを読み込む これをしないと読み込まれない
model->setRootPath(QDir::homePath());
//任意でファイルのフィルタリングができる(ここでは現ディレクトリ「.」を排除している)
model->setFilter(QDir::NoDot | QDir::AllDirs | QDir::Files);
//QMLで読み込めるように追加
engine.rootContext()->setContextProperty("fileSystemModel", model);
engine.rootContext()->setContextProperty("rootPathIndex", model->index(model->rootPath()));

QMLにて読み込む。setContextPropertyで登録した変数が使用できる。modelはきっとQFileSystemModel以外にもあって、標準化されているんだろうなー。

property alias filelist: filelist
TreeView {
    model: fileSystemModel
    rootIndex: rootPathIndex
}

qmlRegisterUncreatableTypeで登録したクラスを使うときは、このように指定した名前、バージョンでimportする。 関係ないけど、onActivatedで急にindex変数が使えることに違和感を覚える。TreeViewのドキュメント見ると書いてあるんだけどさ。

import filesystemmodel 1.0

filelist.onActivated : {
    var url = fileSystemModel.data(index, FileSystemModel.~~~~~~~)
    Qt.openUrlExternally(url)
}

これで最低限のファイル一覧を読み込むことができる。

機能拡張

しかし、これではファイルリストが表示されるだけで、ファイルサイズや最終更新日などの情報は得られない。そこで、QFileSystemModelを継承して独自の機能を追加する。

もちろん継承したクラスで実装した公開メソッドはqmlRegisterUncreatableTypeによってQMLから使えるから、それを活用して情報を得るようにする。

これについては、Qtの公式サンプルを見れば良いと思う。というかほとんどここの情報から学んだから必見。main.cppに継承したクラスが実装されていて、まとまっている。

Qt Quick Controls - File System Browser Example

まとめ

QMLとC++のクラスを紐付けることによってデータの受け渡しをするみたいだ。これはRubyの拡張ライブラリみたいなバインディングと同じなんだね。

C++ではQMLで欲しい情報を得るために継承によって公開メソッドを作り、QML側でメソッドによりset,getをするというのが基本。QML側ではidをコンポーネントごとに割り当てられるからオブジェクト間の連携は楽にできそう。

Qtはバージョンによる違いとかQML前後の情報で混乱しがちだなあ。

参考