プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2022/02/25

[PySide] QListWidget の使い方

event_note2022/02/24 23:19

QListWidget を使っていていろいろはまったのでメモです。

環境

  • Python 3.8.10
  • PySide 6.2.2.1

カスタムウィジェットをセットする

setItemWidget でアイテムとウィジェットを関連付けする必要があります。

custom_widget = CustomWidget()

# Create QListWidgetItem
item = QListWidgetItem(list_widget)
# Set size hint
item.setSizeHint(custom_widget.sizeHint())

# Add QListWidgetItem into QListWidget
self.addItem(item)
self.setItemWidget(item, custom_widget)

先頭行に追加する

insertItem() で 0 行目にアイテムを追加すればいいと思っていたら、実際には最後に追加されてしまいました。
悩んでいたところで以下の記事を見つけたのですが、どうやら QListWidgetItem でアイテムを作成する際、親ウィジェットを指定してはいけないようです。

custom_widget = CustomWidget()

# Create QListWidgetItem
item = QListWidgetItem() # 親を指定しない
# Set size hint
item.setSizeHint(custom_widget.sizeHint())

# Add QListWidgetItem into QListWidget
self.insertItem(0, item)
self.setItemWidget(item, custom_widget)

ちなみに、insertItem よりも setItemWidget を先に処理していると上手く動きませんでした。

アイテムを削除する

takeItem を使います。
削除なのに take というのが分かりづらい・・・。

item = self.takeItem(row)
self.removeItemWidget(item)
del item

ドキュメントによれば、リストから削除されても実体は残っているようなので、del で削除しています。
だから take なのかな?

ちなみに removeItemWidget はアイテムと関連付けられているウィジェットを削除しますが、del item としているので、もしかしたら不要かもしれません。

QListWidget のサイズをコンテンツに合わせる

カスタムウィジェットのサイズに上手く合わないことがあったので、どうしたらいいのか調べていたら、以下の記事を見つけました。

以下のように sizeHint() をオーバーライドすればいいようです。

def sizeHint(self):
    s = QSize()
    s.setHeight(super().sizeHint().height())
    s.setWidth(self.sizeHintForColumn(0))
    return s

ただ、私の場合、上記だとウィジェットとスクロールバーが重なって表示されたりしたので、以下のようにスクロールバーの幅も考慮するように変更しました。

def sizeHint(self):
    s = QSize()
    s.setHeight(super().sizeHint().height())
    s.setWidth(self.sizeHintForColumn(0) + self.verticalScrollBar().sizeHint().width() * 2)
    return s