見出し画像

PySide2 の TreeView / ListView でディレクトリを表示する

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

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

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

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 で上記モデルの設定、setRootIndexIndex で表示するディレクトリを指定しています。

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

リストビューを表示する
リストビューの表示も、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 に addWidge でビューを追加しても 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())

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

この記事は、下記にも記載しています。
PySide2 の TreeView / ListView でディレクトリを表示する | アルトエリア++

参考
Model/View Programming — Qt for Python (Technology Preview)


Note やるからには、サポートがいただけるような役立つ記事を書きたいものです。サポートは資料購入に宛てます。