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
参考 URL
- https://stackoverflow.com/questions/948444/qlistview-qlistwidget-with-custom-items-and-custom-item-widgets
- https://stackoverflow.com/questions/45258159/how-to-add-a-qlistwidgetitem-on-top-of-the-qlistwidget
- https://qiita.com/tatsuteb/items/959700c1d7b42c7c8b5a
- https://stackoverflow.com/questions/6337589/qlistwidget-adjust-size-to-content
- https://stackoverflow.com/questions/59428906/qlistwidget-display-more-items