PySide6でウィジェット分割しサイズを変更可能にする【QSplitter】

python コンピュータ
python

まずはサンプルスクリプトを実行してみます。

import sys
from PySide6.QtWidgets import QApplication,QMainWindow,QSplitter,QPushButton, QVBoxLayout, QWidget, QHBoxLayout
from PySide6.QtWidgets import QFileSystemModel
from PySide6.QtWidgets import QTreeView
from PySide6.QtWidgets import QListView
from PySide6.QtWidgets import QTextEdit
from PySide6.QtWidgets import QLineEdit
from PySide6.QtCore import QSize, Qt
PATH = 'H:/'

# メインウィンドウ
class MyMainWindow(QMainWindow):

    # コンストラクタ
    def __init__(self):
        # スーパー(親)クラスのコンストラクタの呼び出し
        super().__init__()

        model = QFileSystemModel()
        model.setRootPath(PATH)

        ls = QListView()
        ls.setModel(model)
        ls.setRootIndex(model.index(PATH))
        #tr.show()
        text_edit = QTextEdit()
        
        # 左右で分割
        splitter = QSplitter(Qt.Orientation.Horizontal,self)
        splitter.addWidget(ls)
        splitter.addWidget(text_edit)

        address_bar = QLineEdit()
        btn = QPushButton('↑')
        btn.setStyleSheet('QPushButton {padding: 3px 12px;}')

        #self.setCentralWidget(splitter)

        # レイアウトを作成
        layout1 = QHBoxLayout()
        layout1.addWidget(btn)
        layout1.addWidget(address_bar)
        layout1.setContentsMargins(0, 0, 0, 0)
        widget1 = QWidget()
        widget1.setLayout(layout1)

        layout = QVBoxLayout()
        layout.addWidget(widget1)
        layout.addWidget(splitter)
        #self.setLayout(layout)

        # レイアウトをQWidgetに設定し、それをCentralWidgetにする
        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec())

実行すると以下のような感じになります。

QSplitterの説明のはずが関係のないコードが沢山あるのは見逃してください。

 

QSplitterのコードは以下の部分に成ります。
# 左右で分割
splitter = QSplitter(Qt.Orientation.Horizontal,self)
splitter.addWidget(ls)
splitter.addWidget(text_edit)

QSplitterのオブジェクトを生成時引数にQt.Orientation.Horizontalを指定することで水平方向に分割されます。
生成されたオブジェクトsplitter.addWidget()でウィジェットを渡してあげています。
サンプルではファイルの一覧が表示されている左側部分と何も入力されていないテキストボックスの右側で分割されています。
境界部をマウスでドラックすることでウィジェットのサイズを変更することが出来ます。

QSplitter的には以上ですが、サンプルのコードの様な見た目を作るためにレイアウトを使いました。
調べたことをまとめると
QHBoxLayout()でウィジェットを横方法に配置
QVBoxLayout()でウィジェットを縦方法に配置
生成されたLayoutQWidget()のオブジェクトにsetLayout()に適用する。

最終的にLayoutが適用されたQWidget()QMainWindowself.setCentralWidget()で登録します。

ウィジェットにレイアウトを適用するのはなんとなく理解できますし、ウィジェット同士の組み合わせることで複数のレイアウトを適用することが出来ることも確認できました。ただ最後の.setCentralWidget()が理解が追い付いていません。

話は変わりますが、これだけのコードでListViewにアイコン付きでファイルの一覧が表示されています。
QFileSystemModel()というファイルシステムのモデルが用意されていて、ListViewのデータソースとしてバインディングしてあげれば、このようなファイルの一覧が表示されいました。さすがにファイルやフォルダをクリックしても何も起きませんが、このようなクラスまでQtでは用意されており、便利であると思う反面、欲しい機能が用意してあるか調べることが多くなりそうな感じもします。

あと、各ウィジェットの配置の位置やサイズを直接指定することなくレイアウトされており、QSplitterもそうですがウィンドウの操作にも各ウィジェットが良い感じ連動してくれています。

とりあえず試行錯誤して希望するレイアウトにすることが出来ましたが、何故このコードでこのような結果になったのか、理解が出来ていない部分が多いので、そのあたりはオイオイ学習していきたいと思います。

コメント