コンテンツにスキップ

List/Tree Widgetを使おう(1) 基本編

PySide には Model を自分で実装して使用する TreeView / ListView がありますが
もう少し手軽にリストを表示したりしたい場合に使用できる「 ListWidget / TreeWidget」が
あります。

今回は、この TreeWidget の基本的な使い方を見ていきたいと思います。

ListWidget

ListWidget は、その名の通り1列のみのシンプルなリストを作成できるウィジェットです。
この基本的なサンプルが以下のコードです。

 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
# -*- coding: utf-8 -*-
import sys
from PySide2.QtWidgets import (QApplication, QMainWindow, QListWidget, QListWidgetItem)
from PySide2.QtGui import (QBrush, QColor)
from PySide2.QtCore import Qt


class SampleUI(QMainWindow):

    def __init__(self, parent=None):
        super().__init__(parent)

        self.listWidget = QListWidget()
        self.setCentralWidget(self.listWidget)
        # Listにアイテムを追加する
        for i in ['a', 'b', 'c', 'd', 'e']:
            item = QListWidgetItem(i, self.listWidget)
            # 背景色を指定したい場合
            item.setBackground(QBrush(QColor(255, 0, 0)))

        self.listWidget.itemClicked.connect(self.clicked)

    def clicked(self, item):
        # Signalで受け取る場合
        print(item.text())
        # listWidgetから選択されている値を取得したい場合
        print(self.listWidget.currentItem().text())


if __name__ == "__main__":
    app = QApplication(sys.argv)

    ui = SampleUI()
    ui.show()
    sys.exit(app.exec_())

ListWidget に項目を追加する場合は、
List に表示するアイテムは、「ListWidgetItem」というクラスを使用します。

Item は、List に表示されている項目を管理するためのクラスで、
表示する文字列や Icon、背景色、フォントなど
1項目をどのように表示するかは、この Item 側で指定します。

1
2
3
4
        for i in ['a', 'b', 'c', 'd', 'e']:
            item = QListWidgetItem(i, listWidget)
            brush = QBrush(QColor(255, 0, 0))
            item.setBackground(brush)

例として、背景色を帰る場合。
Item に対して setBackground を指定することで

色を指定することができました。

現在選択中の項目を取得したい場合も、 currentItem() で QListWidgetItem を取得できるので
そこから item.text() で、文字列を取得したり、背景色などの値も取得できます。

TreeWidget

次に TreeWidget。
こちらも ListWidget と同じく QTreeWidgetItem を使用して項目を追加していきます。

 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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# -*- coding: utf-8 -*-
import sys
# from PySide2.QtCore import ()
# from PySide2.QtGui import ()
from PySide2.QtWidgets import (QApplication, QMainWindow, QTreeWidget, QTreeWidgetItem)


class SampleUI(QMainWindow):

    def __init__(self, parent=None):
        super().__init__(parent)

        treeWidget = QTreeWidget()
        treeWidget.setColumnCount(2)
        treeWidget.setHeaderLabels(['名前', "説明"])
        self.setCentralWidget(treeWidget)
        # Listにアイテムを追加する
        rootItem = QTreeWidgetItem()
        rootItem.setText(0, "hoge")
        rootItem.setText(1, "ほげです。")
        # 一番上のItemを追加
        treeWidget.addTopLevelItem(rootItem)
        # その子供にもItemを追加
        for i in ['A', 'B', 'C']:
            cItem = QTreeWidgetItem()
            cItem.setText(0, i)
            rootItem.addChild(cItem)

        treeWidget.itemClicked.connect(self.clicked)

    def clicked(self, item):

        print(item.text(0))  # クリックしたItemをプリント
        # 子供のItemを取得する場合
        if item.childCount() == 0:
            print('子供はいません')
        else:
            for i in range(item.childCount()):
                print(item.child(i).text(0))

        # 親を取得
        if item.parent():
            print(item.parent().text(0))
        else:
            print('RootItemです。')

if __name__ == "__main__":
    app = QApplication(sys.argv)

    ui = SampleUI()
    ui.show()
    sys.exit(app.exec_())

実行結果はこのようになります。
List との違いは、

列が複数あるので、 setText でどの列に対して表示するかを指定します。

1
2
3
        rootItem = QTreeWidgetItem()
        rootItem.setText(0, "hoge")
        rootItem.setText(1, "ほげです。")

もう一つが、
TreeWidgetItem は、List とは違い addChild をすることで木構造を作成します。

1
treeWidget.addTopLevelItem(rootItem)

TopLebelItem が、TreeWidget の直下に表示される Item です。
それ以下の子 Item は、

1
2
3
4
        for i in ['A', 'B', 'C']:
            cItem = QTreeWidgetItem()
            cItem.setText(0, i)
            rootItem.addChild(cItem)

親 Item の子供として addChild で Item を追加します。

Item の親・子を取得する場合

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    def clicked(self, item):

        print(item.text(0))  # クリックしたItemをプリント
        # 子供のItemを取得する場合
        if item.childCount() == 0:
            print('子供はいません')
        else:
            for i in range(item.childCount()):
                print(item.child(i).text(0))

        # 親を取得
        if item.parent():
            print(item.parent().text(0))
        else:
            print('RootItemです。')

選択している Item を取得するのは List と共通ですが、それ以外に
Item の親や子を取得したりすることができます。

まとめ

以上が ListWidget / TreeWidget の基本的な使い方でした。
重要なポイントは、それぞれ「Item」クラスを使用することでリストに追加できること
各項目の設定もこの Item でできること。
TreeView の場合は、Item を親子化することで、木構造を作れること です。

TreeView に比べると、細かいカスタマイズはできませんが
多くの場合はこの Widget と Item で対応できるので
List を作成したい場合はおすすめです。