サイドバーの「Django ドキュメント検索」というプレースホルダの入った検索では、Django ドキュメント (Django 2.1) の公式サイト内を検索できます
PySide2 の QTreeView / QListView でディレクトリを表示する

目次

Qt for Python (PySide2) のオフィシャルバージョンが公開されました。(QtのPythonバインディング「Qt for Python」、初の公式リリース | OSDN Magazine)ただし、Qt 本家のドキュメントと比較するとまだまだ情報が少なく、チュートリアルをなぞってもうまく動かないなど、誤りも多く見受けられます。自分自身の勉強も兼ねて、試行錯誤で得られた情報をピックアップして発信していきます。

はじめに

Qt for Python (PySide2) で複数アイテムを表示する際には、List / Tree / Table のそれぞれに対して Widget 系と View 系の二種類のクラスが用意されています。基本的には、ごく簡単なプログラムでない限り Model / View に基づいた View 系 (QListView / QTreeView / QTableView) を使うのが良いようです。

ここでは Model/View Programming — Qt for Python (Technology Preview) を参考に、ツリービューとリストビューを使って、ディレクトリを表示させます。

ツリービューを表示する

まずは、QFileSystemModelQTreeView を使ってディレクトリのツリー表示を行うコードを書いてみます。

import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QFileSystemModel
from PySide2.QtWidgets import QTreeView


# 表示するパス
PATH = '/usr'


def main():
    app = QApplication(sys.argv)

    # QFileSystemModel を設定する
    model = QFileSystemModel()
    model.setRootPath(PATH)

    # TreeView
    tr = QTreeView()
    tr.setModel(model)
    tr.setRootIndex(model.index(PATH))
    tr.show()

    return app.exec_()


if __name__ == '__main__':
    sys.exit(main())

PATH には実在するディレクトリを記述してください。上記例は Linux です。Windows の c ドライブルートなら下記のように設定します。

PATH = 'C:\\'

表示する対象はモデルで定義します。ここでは、ディレクトリを表示させたいので QFileSystemModel をインスタンス化し、setRootPath で 上記 PATH を対象としています。

QTreeView をインスタンス化して setModel で上記モデルの設定、setRootIndex で表示するディレクトリを指定しています。

実行すると下記のようにツリービューが表示できます。

リストビューを表示する

リストビューの表示も、QListView を使うだけでツリービューと同様に書けます。

import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QFileSystemModel
from PySide2.QtWidgets import QListView

# 表示するパス
PATH = '/usr'

def main():
    app = QApplication(sys.argv)

    # QFileSystemModel を設定する
    model = QFileSystemModel()
    model.setRootPath(PATH)

    # ListView
    ls = QListView()
    ls.setModel(model)
    ls.setRootIndex(model.index(PATH))
    ls.show()

    return app.exec_()


if __name__ == '__main__':
    sys.exit(main())

実行してみます。

ツリービューとリストビューの選択を同期させる

最後に、ツリービューとリストビューを同時に表示して、一方を選択するともう一方の該当フォルダが選択されるようにしてみます。

ここでは 2つのビューを表示するため、QSplitter (分割機能を提供する QFrame) がツリービューとリストビューの親となるようにします。

splitter = QSplitter()
tr = QTreeView(splitter)
ls = QListView(splitter)

下記のように一旦親を指定せずにビューを生成してから、splitter に addWidget でビューを追加しても OK です。

splitter = QSplitter()
tr = QTreeView()
ls = QListView()
splitter.addWidget(tr)
splitter.addWidget(ls)

2つのビューの選択を同期させるには、setSelectionModel、selectionModel を使います。

view1.setSelectionModel(view2.selectionModel())

以上をまとめると下記のようなコードになります。

import sys
from PySide2.QtWidgets import QApplication
from PySide2.QtWidgets import QSplitter
from PySide2.QtWidgets import QFileSystemModel
from PySide2.QtWidgets import QTreeView
from PySide2.QtWidgets import QListView

# 表示するパス
PATH = '/usr'

def main():
    app = QApplication(sys.argv)
    splitter = QSplitter()

    model = QFileSystemModel()
    model.setRootPath(PATH)

    # TreeView
    tr = QTreeView(splitter)
    tr.setModel(model)
    tr.setRootIndex(model.index(PATH))

    # ListView
    ls = QListView(splitter)
    ls.setModel(model)
    ls.setRootIndex(model.index(PATH))

    # 2つのビューの選択を同期させる
    ls.setSelectionModel(tr.selectionModel())

    splitter.setWindowTitle(("同じディレクトリモデルを2つのビューで表示する"))
    splitter.show()

    return app.exec_()


if __name__ == '__main__':
    sys.exit(main())

実行して一方のビューのアイテムを選択すると、もう一方も選択されるのが確認できます。

※注)この状態ではリストビューの階層が固定されているので、ツリービューで下の階層に行った時には同期できません。解決法は未確認です。判明したら追加記事を作成します。

参考

低価格なのに高速・多機能・高セキュリティ 月額400円(税別)から最大容量100GB WordPress専用高速サーバー Z.com WP
おすすめの記事