
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) を参考に、ツリービューとリストビューを使って、ディレクトリを表示させます。
ツリービューを表示する
まずは、QFileSystemModel と QTreeView を使ってディレクトリのツリー表示を行うコードを書いてみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
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 ドライブルートなら下記のように設定します。
1 |
PATH = 'C:\\' |
表示する対象はモデルで定義します。ここでは、ディレクトリを表示させたいので QFileSystemModel をインスタンス化し、setRootPath で 上記 PATH を対象としています。
QTreeView をインスタンス化して setModel で上記モデルの設定、setRootIndex で表示するディレクトリを指定しています。
実行すると下記のようにツリービューが表示できます。
リストビューを表示する
リストビューの表示も、QListView を使うだけでツリービューと同様に書けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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) がツリービューとリストビューの親となるようにします。
1 2 3 |
splitter = QSplitter() tr = QTreeView(splitter) ls = QListView(splitter) |
下記のように一旦親を指定せずにビューを生成してから、splitter に addWidget でビューを追加しても OK です。
1 2 3 4 5 |
splitter = QSplitter() tr = QTreeView() ls = QListView() splitter.addWidget(tr) splitter.addWidget(ls) |
2つのビューの選択を同期させるには、setSelectionModel、selectionModel を使います。
1 |
view1.setSelectionModel(view2.selectionModel()) |
以上をまとめると下記のようなコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
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()) |
実行して一方のビューのアイテムを選択すると、もう一方も選択されるのが確認できます。
※注)この状態ではリストビューの階層が固定されているので、ツリービューで下の階層に行った時には同期できません。解決法は未確認です。判明したら追加記事を作成します。