Wizard Notes

Python, JavaScript を使った音楽信号分析の技術録、作曲活動に関する雑記

PyQt: QScrollAreaを使ってスクロールバーを追加する

f:id:Kurene:20210218171115g:plain

PyQt でスクロールバーを追加する方法としては、QScrollAreaがあります。

QScrollAreaの利用シーンとしては、以下の2パターンに分けることができます。

  1. QWidget/QMainWindow 上の特定の領域でスクロールしたい
  2. QWidgetを継承・カスタマイズしたオブジェクト自体にスクロールを追加したい

特に 1 のパターンでは、以下の参考ページの方法が参考になります。

dungeonneko.hatenablog.com

ここで、widgetlayoutの包含関係において、

QScrollArea > QWidget > (任意のlaytout) > (任意のQWidget)

というように、QWidgetオブジェクトを挟む必要があることに注意してください。

2 のパターンも上記の実装で実現できますが、QScrollAreaQWidgetの子クラスであるため、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_())