PyQt でスクロールバーを追加する方法としては、QScrollArea
があります。
QScrollArea
の利用シーンとしては、以下の2パターンに分けることができます。
QWidget
/QMainWindow
上の特定の領域でスクロールしたいQWidget
を継承・カスタマイズしたオブジェクト自体にスクロールを追加したい
特に 1 のパターンでは、以下の参考ページの方法が参考になります。
ここで、widget
とlayout
の包含関係において、
QScrollArea
> QWidget
> (任意のlaytout
) > (任意のQWidget
)
というように、QWidget
オブジェクトを挟む必要があることに注意してください。
2 のパターンも上記の実装で実現できますが、QScrollArea
はQWidget
の子クラスであるため、QScrollArea
を継承することでよりカスタマイズしやすい形で書くことができます。
以下の実装の実行例は記事最上部のGIFとなっております。
#!/usr/bin/python # -*- Coding: utf-8 -*- import sys from PyQt5.QtWidgets import ( QWidget, QLabel, QVBoxLayout, QScrollArea, QPushButton, QApplication ) class MyWidget(QScrollArea): def __init__(self, n_buttons): super().__init__() self.setWidgetResizable(True) inner = QWidget() layout = QVBoxLayout() # ラベル設置 self.label = QLabel('?', self) layout.addWidget(self.label) # ボタン設置 for k in range(n_buttons): button = QPushButton(f"Button {k}") button.clicked.connect(self.on_change) layout.addWidget(button) inner.setLayout(layout) self.setWidget(inner) def on_change(self): button = self.sender() self.label.setText(button.text()) self.label.adjustSize() if __name__ == '__main__': app = QApplication(sys.argv) w = MyWidget(16) w.show() app.exit(app.exec_())