QAbstractScrollArea::scrollBarWidgets()の代替手段とQtレイアウトの活用

2025-05-26

QAbstractScrollArea::scrollBarWidgets() は、Qtのウィジェットである QAbstractScrollArea クラスのメソッドです。このメソッドは、スクロールバーの隣に配置された追加のウィジェットのリストを返します。

QAbstractScrollArea は、ビューポート(表示領域)とその周りにスクロールバーを持つウィジェットの基本的な機能を提供します。例えば、QScrollAreaQTextEdit など、スクロール機能を持つ多くのQtウィジェットは QAbstractScrollArea を継承しています。

使い方

scrollBarWidgets() メソッドは、引数として Qt::Alignment フラグを取ります。これにより、どの位置(水平スクロールバーの左右、または垂直スクロールバーの上下)に追加されたウィジェットを取得するかを指定できます。

  • Qt::AlignBottom: 垂直スクロールバーの下側に配置されたウィジェット
  • Qt::AlignTop: 垂直スクロールバーの上側に配置されたウィジェット
  • Qt::AlignRight: 水平スクロールバーの右側に配置されたウィジェット
  • Qt::AlignLeft: 水平スクロールバーの左側に配置されたウィジェット

このメソッドは、指定された位置に追加された QWidget のリスト(QList<QWidget *>)を返します。

何のために使うのか?

通常、スクロールバーの隣にはスクロール機能に関連する補助的なウィジェット(例えば、スクロール範囲を示すミニマップや、特定の位置へジャンプするボタンなど)を配置したい場合があります。QAbstractScrollArea は、そのようなカスタムウィジェットをスクロールバーの横に簡単に追加できる addScrollBarWidget() メソッドを提供しています。

scrollBarWidgets() メソッドは、すでに追加されているそれらのウィジェットを取得したい場合に役立ちます。例えば、追加したウィジェットの状態を変更したり、削除したりする場合に、このメソッドでそのウィジェットへのポインタを取得することができます。

#include <QApplication>
#include <QAbstractScrollArea>
#include <QScrollBar>
#include <QPushButton>
#include <QVBoxLayout>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QAbstractScrollArea scrollArea;
    scrollArea.setMinimumSize(400, 300);

    // ダミーのビューポートウィジェットを設定
    QWidget *viewportWidget = new QWidget();
    viewportWidget->setFixedSize(800, 600); // ビューポートより大きくしてスクロール可能にする
    scrollArea.setViewport(viewportWidget);

    // スクロールバーの隣にウィジェットを追加
    QPushButton *button1 = new QPushButton("Top Button");
    QPushButton *button2 = new QPushButton("Bottom Button");
    QPushButton *button3 = new QPushButton("Left Button");

    scrollArea.addScrollBarWidget(button1, Qt::AlignTop);
    scrollArea.addScrollBarWidget(button2, Qt::AlignBottom);
    scrollArea.addScrollBarWidget(button3, Qt::AlignLeft);

    // 追加したウィジェットを取得して情報を表示
    QList<QWidget *> topWidgets = scrollArea.scrollBarWidgets(Qt::AlignTop);
    qDebug() << "Top Widgets Count:" << topWidgets.size();
    for (QWidget *w : topWidgets) {
        qDebug() << "  Top Widget Name:" << w->objectName();
    }

    QList<QWidget *> bottomWidgets = scrollArea.scrollBarWidgets(Qt::AlignBottom);
    qDebug() << "Bottom Widgets Count:" << bottomWidgets.size();
    for (QWidget *w : bottomWidgets) {
        qDebug() << "  Bottom Widget Name:" << w->objectName();
    }
    
    QList<QWidget *> leftWidgets = scrollArea.scrollBarWidgets(Qt::AlignLeft);
    qDebug() << "Left Widgets Count:" << leftWidgets.size();
    for (QWidget *w : leftWidgets) {
        qDebug() << "  Left Widget Name:" << w->objectName();
    }

    scrollArea.show();

    return a.exec();
}

この例では、QAbstractScrollArea を作成し、addScrollBarWidget() を使ってボタンをスクロールバーの隣に追加しています。その後、scrollBarWidgets() を使って追加したボタンへのポインタを取得し、その数や名前を表示しています。



想定したウィジェットが返されない(空のリストが返る)

原因
scrollBarWidgets() メソッドは、あくまで既に addScrollBarWidget() で追加されているウィジェットを返します。以下のいずれかの原因が考えられます。

  • ウィジェットが別の親オブジェクトに移動された
    addScrollBarWidget() で追加されたウィジェットは、QAbstractScrollArea の内部で管理されますが、手動でそのウィジェットの親を変更した場合、予期しない動作になる可能性があります。
  • ウィジェットが既に削除されている
    以前に追加したウィジェットを何らかの理由で削除した後に scrollBarWidgets() を呼び出している。
  • 誤った Qt::Alignment を指定している
    ウィジェットを追加した際の Qt::Alignment と、scrollBarWidgets() で取得しようとしている Qt::Alignment が一致していない。例えば、Qt::AlignTop で追加したのに Qt::AlignBottom で取得しようとしている場合など。
  • ウィジェットがまだ追加されていない
    addScrollBarWidget() を呼び出す前に scrollBarWidgets() を呼び出している。

トラブルシューティング

  • デバッグ出力 (qDebug()) を使用して、addScrollBarWidget() 呼び出し後に scrollBarWidgets().size() の値を確認し、期待通りの数のウィジェットがリストに含まれているかを確認してください。
  • scrollBarWidgets() に渡す Qt::Alignment が、addScrollBarWidget() で使用した Qt::Alignment と一致していることを確認してください。
  • addScrollBarWidget() が正しく呼び出され、ウィジェットが追加されていることを確認してください。

返されたウィジェットが期待する型ではない

原因
scrollBarWidgets()QList<QWidget *> を返します。これは、追加されたウィジェットが QWidget のポインタとして返されることを意味します。もし、追加したウィジェットが QPushButtonQLabel のような特定の派生クラスであれば、ダウンキャストが必要になります。しかし、誤った型にキャストしようとすると、実行時エラーや未定義動作を引き起こす可能性があります。

トラブルシューティング

  • 返された QWidget* を目的の派生クラスにダウンキャストする前に、qobject_cast<DesiredWidgetType*>(widget) を使用してキャストが安全に行えるか確認してください。qobject_cast は、安全なダウンキャストを提供し、キャストが失敗した場合は nullptr を返します。

    QList<QWidget *> widgets = scrollArea->scrollBarWidgets(Qt::AlignTop);
    for (QWidget *w : widgets) {
        QPushButton *button = qobject_cast<QPushButton*>(w);
        if (button) {
            // button は QPushButton として安全に扱える
            button->setText("Updated Text");
        } else {
            qDebug() << "Warning: Widget is not a QPushButton.";
        }
    }
    

スクロールエリアのレイアウトが崩れる、またはウィジェットが見えない

原因
これは scrollBarWidgets() 自体の直接的な問題ではありませんが、addScrollBarWidget() で追加したウィジェットのサイズポリシーやレイアウトの管理が不適切な場合に発生することがあります。

  • 複雑なカスタムウィジェットの配置
    addScrollBarWidget() は比較的シンプルなウィジェットの追加に適していますが、非常に複雑なレイアウトを持つカスタムウィジェットを配置しようとすると、期待通りの表示にならないことがあります。
  • サイズポリシーの不一致
    追加したウィジェットの sizePolicy() が、スクロールエリアのレイアウトと適切に連携していない。

トラブルシューティング

  • もしレイアウトの問題が深刻な場合は、addScrollBarWidget() を使用する代わりに、QGridLayoutQVBoxLayoutQHBoxLayout などの標準的なQtレイアウトマネージャーを使用して、スクロールエリア全体とスクロールバー、追加ウィジェットを構成することを検討してください。これはより柔軟な制御を提供しますが、実装が複雑になる場合があります。
  • QAbstractScrollArea のビューポートウィジェットのレイアウトと、スクロールバーウィジェットのサイズ関係を考慮してください。
  • 追加するウィジェットの setSizePolicy() を適切に設定してください。例えば、QSizePolicy::FixedQSizePolicy::Preferred など、そのウィジェットの振る舞いに合わせて調整します。

メモリリーク(QWidget のポインタ管理)

原因
scrollBarWidgets()QWidget* のリストを返しますが、これは所有権を転送しません。つまり、リストから取得したウィジェットを自分で delete してはいけません。ウィジェットは QAbstractScrollArea の内部で管理されています。もし誤って delete してしまうと、二重解放やクラッシュの原因になります。

  • もしウィジェットを明示的に削除したい場合は、QAbstractScrollArea::removeScrollBarWidget() を使用します。これにより、スクロールエリアからウィジェットが取り除かれ、その後ウィジェットの削除を自分で行うことができます(ただし、通常はQtの親子の仕組みにより自動的に削除されます)。
  • scrollBarWidgets() から取得したポインタは、ウィジェットへの参照としてのみ使用し、その寿命を管理しようとしないでください。ウィジェットの削除は QAbstractScrollArea が行います。


QAbstractScrollArea::scrollBarWidgets() は、QAbstractScrollArea(またはその派生クラス、例: QScrollArea, QTextEdit)に addScrollBarWidget() メソッドで追加されたカスタムウィジェットのリストを取得するために使用されます。このメソッドは、スクロールバーの特定の位置(上、下、左、右)に配置されたウィジェットを対象とします。

以下の例では、QScrollArea を使用して、そのスクロールバーの隣にカスタムボタンを追加し、後でそれらのボタンにアクセスしてテキストを変更する方法を示します。

例1: スクロールバーの隣にボタンを追加し、後でそのボタンを取得して操作する

この例では、QScrollArea を作成し、水平スクロールバーの右側と垂直スクロールバーの下側にボタンを追加します。その後、scrollBarWidgets() を使用してこれらのボタンへのポインタを取得し、それらのテキストを更新します。

main.cpp

#include <QApplication>
#include <QMainWindow>
#include <QScrollArea>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QDebug> // デバッグ出力用

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QMainWindow window;
    window.setWindowTitle("QAbstractScrollArea::scrollBarWidgets() Example");
    window.resize(600, 400);

    // QScrollArea を作成
    QScrollArea *scrollArea = new QScrollArea(&window);
    window.setCentralWidget(scrollArea);

    // スクロールされるコンテンツ(大きめの QLabel)を作成
    QLabel *contentLabel = new QLabel("これは非常に長いテキストを含むコンテンツです。\n"
                                     "スクロールして全体を表示してください。\n"
                                     "行が多すぎて、ビューポートに収まらないはずです。\n"
                                     "このテキストは、QAbstractScrollAreaのビューポートに表示されます。\n"
                                     "QAbstractScrollAreaは、コンテンツがビューポートより大きい場合にスクロールバーを提供します。\n"
                                     "ここにさらに多くの行を追加して、スクロールが必要になるようにします。\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "これで十分な長さになったはずです。");
    contentLabel->setWordWrap(true); // テキストが折り返されるように設定
    contentLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft); // 左上揃え

    // QScrollArea にコンテンツを設定(QScrollAreaがcontentLabelの所有権を持つ)
    scrollArea->setWidget(contentLabel);
    scrollArea->setWidgetResizable(true); // コンテンツのサイズに合わせてビューポートを調整

    // スクロールバーの隣にカスタムウィジェットを追加
    // 水平スクロールバーの右側
    QPushButton *hScrollBarRightButton = new QPushButton("H-Right Btn");
    hScrollBarRightButton->setObjectName("HorizontalRightButton"); // オブジェクト名を設定
    scrollArea->addScrollBarWidget(hScrollBarRightButton, Qt::AlignRight);

    // 垂直スクロールバーの下側
    QPushButton *vScrollBarBottomButton = new QPushButton("V-Bottom Btn");
    vScrollBarBottomButton->setObjectName("VerticalBottomButton"); // オブジェクト名を設定
    scrollArea->addScrollBarWidget(vScrollBarBottomButton, Qt::AlignBottom);

    // ----------------------------------------------------------------------
    // ここからが QAbstractScrollArea::scrollBarWidgets() の使用例
    // ----------------------------------------------------------------------

    qDebug() << "--- スクロールバーの隣に配置されたウィジェットの情報を取得 ---";

    // 水平スクロールバーの右側のウィジェットを取得
    QList<QWidget *> horizontalRightWidgets = scrollArea->scrollBarWidgets(Qt::AlignRight);
    qDebug() << "水平スクロールバー右側のウィジェット数:" << horizontalRightWidgets.size();
    for (QWidget *widget : horizontalRightWidgets) {
        qDebug() << "  ウィジェット名:" << widget->objectName();
        // QPushButton にダウンキャストしてテキストを変更
        if (QPushButton *button = qobject_cast<QPushButton*>(widget)) {
            button->setText("更新済み H-Right");
            qDebug() << "  テキストを更新しました。";
        }
    }

    // 垂直スクロールバーの下側のウィジェットを取得
    QList<QWidget *> verticalBottomWidgets = scrollArea->scrollBarWidgets(Qt::AlignBottom);
    qDebug() << "垂直スクロールバー下側のウィジェット数:" << verticalBottomWidgets.size();
    for (QWidget *widget : verticalBottomWidgets) {
        qDebug() << "  ウィジェット名:" << widget->objectName();
        // QPushButton にダウンキャストしてテキストを変更
        if (QPushButton *button = qobject_cast<QPushButton*>(widget)) {
            button->setText("更新済み V-Bottom");
            qDebug() << "  テキストを更新しました。";
        }
    }
    
    // 存在しない位置のウィジェットを取得しようとする例 (空のリストが返る)
    QList<QWidget *> topWidgets = scrollArea->scrollBarWidgets(Qt::AlignTop);
    qDebug() << "垂直スクロールバー上側のウィジェット数 (追加していない):" << topWidgets.size();


    window.show();

    return a.exec();
}
  1. QScrollArea の作成とコンテンツの設定
    QScrollArea を作成し、その中に表示するコンテンツとして QLabel を設定しています。setWidgetResizable(true) を呼び出すことで、QScrollArea が自動的にコンテンツのサイズに合わせてビューポートを調整するようにしています。

  2. addScrollBarWidget() でウィジェットを追加
    QPushButton のインスタンスを作成し、scrollArea->addScrollBarWidget(widget, alignment) を使って、水平スクロールバーの右側 (Qt::AlignRight) と垂直スクロールバーの下側 (Qt::AlignBottom) にそれぞれ追加しています。setObjectName() を使って、ウィジェットに識別用の名前を設定している点がポイントです。

  3. scrollBarWidgets() でウィジェットを取得
    scrollArea->scrollBarWidgets(Qt::AlignRight)scrollArea->scrollBarWidgets(Qt::AlignBottom) を呼び出すことで、それぞれの位置に追加されたウィジェットのリスト (QList<QWidget *>) を取得します。

  4. 取得したウィジェットの操作
    取得したリストをループ処理し、各 QWidget* ポインタを qobject_cast<QPushButton*>(widget) を使って QPushButton* に安全にダウンキャストしています。キャストが成功した場合(buttonnullptr でない場合)、そのボタンのテキストを setText() で変更しています。 qobject_cast は、Qtのメタオブジェクトシステムを利用した安全なダウンキャストメカニズムです。これにより、誤った型にキャストしようとした場合にクラッシュを防ぎ、nullptr を返すことでプログラムがその状況を適切に処理できるようにします。

  5. 存在しない位置の確認
    最後に、Qt::AlignTop のように、実際にはウィジェットを追加していない位置を指定して scrollBarWidgets() を呼び出した場合、空のリストが返されることをデバッグ出力で確認しています。



QAbstractScrollArea::scrollBarWidgets() は、主にスクロールバーに密接に関連する小さな補助ウィジェット(例えば、スクロール位置を示すミニマップ、特定のセクションへのショートカットボタンなど)を配置し、それらにプログラムからアクセスする場合に有用です。

しかし、より複雑なレイアウトや、スクロール機能とは独立したコントロールを配置したい場合、以下の代替方法を検討できます。

標準的なレイアウトマネージャーを使用する

これは最も一般的で柔軟なアプローチです。QAbstractScrollArea(またはその派生クラス)を、他のウィジェットとともにQVBoxLayoutQHBoxLayoutQGridLayoutなどの標準的なレイアウトに配置します。

利点

  • UIデザイナーとの連携
    Qt Designer を使用して、複雑なレイアウトを簡単に構築できます。
  • 標準的なQtの振る舞い
    レイアウトマネージャーはQtの基本的なレイアウトシステムなので、予測可能な振る舞いをします。
  • 視覚的分離
    スクロールエリアの機能から独立したコントロールを、視覚的にも分離して配置できます。
  • 柔軟性
    レイアウトマネージャーは、ウィジェットの配置、サイズ変更、間隔などを非常に細かく制御できます。スクロールエリアの上下左右だけでなく、どんな場所にも自由にウィジェットを配置できます。

欠点

  • 実装の複雑さ(場合による)
    addScrollBarWidget() よりも、レイアウトのネストやウィジェットのサイズポリシーの設定など、考慮すべき点が増える可能性があります。
  • スクロールバーとの物理的な結合がない
    addScrollBarWidget() のようにスクロールバーに「隣接して」配置されるわけではないため、スクロールバーが非表示になったときに自動的にウィジェットが配置され直すといった挙動は期待できません。その場合、手動でレイアウトを調整する必要があるかもしれません。

コード例

#include <QApplication>
#include <QMainWindow>
#include <QScrollArea>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QWidget> // 汎用ウィジェットの親として使用

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QMainWindow window;
    window.setWindowTitle("Layout Manager Example");
    window.resize(700, 500);

    // メインウィジェットとメインレイアウトを作成
    QWidget *mainWidget = new QWidget(&window);
    QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget);
    window.setCentralWidget(mainWidget);

    // 上部にコントロールボタンを配置
    QHBoxLayout *topControlsLayout = new QHBoxLayout();
    QPushButton *zoomInButton = new QPushButton("Zoom In");
    QPushButton *zoomOutButton = new QPushButton("Zoom Out");
    topControlsLayout->addWidget(zoomInButton);
    topControlsLayout->addWidget(zoomOutButton);
    topControlsLayout->addStretch(); // ボタンを左に寄せる

    mainLayout->addLayout(topControlsLayout);

    // スクロールエリアを作成
    QScrollArea *scrollArea = new QScrollArea();
    QLabel *contentLabel = new QLabel("この非常に長いテキストはスクロールエリアのコンテンツです...\n"
                                     "(以下略、十分な量のテキスト)\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "...........................................................................\n"
                                     "これで十分な長さになったはずです。");
    contentLabel->setWordWrap(true);
    scrollArea->setWidget(contentLabel);
    scrollArea->setWidgetResizable(true);

    mainLayout->addWidget(scrollArea);

    // 下部に別のコントロールボタンを配置
    QHBoxLayout *bottomControlsLayout = new QHBoxLayout();
    QPushButton *saveButton = new QPushButton("Save");
    QPushButton *printButton = new QPushButton("Print");
    bottomControlsLayout->addStretch(); // ボタンを右に寄せる
    bottomControlsLayout->addWidget(saveButton);
    bottomControlsLayout->addWidget(printButton);

    mainLayout->addLayout(bottomControlsLayout);

    window.show();

    return a.exec();
}

この例では、ズームボタンと保存/印刷ボタンがスクロールエリアの上下にそれぞれ配置されており、スクロールエリアとは独立してレイアウトされています。

QAbstractScrollArea::cornerWidget() を使用する

QAbstractScrollArea は、水平スクロールバーと垂直スクロールバーが交差する「角」に1つのウィジェットを配置するための setCornerWidget() メソッドを提供しています。このウィジェットは通常、スクロールバーが存在する場合にのみ表示されます。

利点

  • 自動的な表示/非表示
    スクロールバーの表示状態に応じて自動的に表示/非表示が切り替わります。
  • 特定の用途に特化
    スクロールバーの角に何かを配置したい場合に非常にシンプルです。

欠点

  • scrollBarWidgets() とは独立
    scrollBarWidgets() でこのウィジェットを取得することはできません(別途 cornerWidget() メソッドが存在します)。
  • 配置場所が1箇所のみ
    角の1箇所にしかウィジェットを配置できません。スクロールバーの左右や上下には配置できません。

コード例

#include <QApplication>
#include <QMainWindow>
#include <QScrollArea>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QMainWindow window;
    window.setWindowTitle("Corner Widget Example");
    window.resize(600, 400);

    QScrollArea *scrollArea = new QScrollArea(&window);
    window.setCentralWidget(scrollArea);

    QLabel *contentLabel = new QLabel("非常に長いコンテンツ...");
    contentLabel->setWordWrap(true);
    contentLabel->setFixedSize(800, 600); // スクロールバーが表示されるように固定サイズにする
    scrollArea->setWidget(contentLabel);
    scrollArea->setWidgetResizable(false); // 固定サイズなのでResizableはfalse

    // 角にウィジェットを配置
    QPushButton *cornerButton = new QPushButton("Corner");
    scrollArea->setCornerWidget(cornerButton);

    // 角ウィジェットを取得
    QWidget *retrievedCornerWidget = scrollArea->cornerWidget();
    if (retrievedCornerWidget) {
        qDebug() << "Corner widget found:" << retrievedCornerWidget->objectName();
        // ここでretrievedCornerWidgetを操作可能
        if (QPushButton *button = qobject_cast<QPushButton*>(retrievedCornerWidget)) {
            button->setText("C-Btn");
        }
    }

    window.show();

    return a.exec();
}

QScrollBar オブジェクトに直接アクセスして親を変更する(非推奨/高度なケース)

QAbstractScrollArea は、horizontalScrollBar()verticalScrollBar() メソッドを通じて、内部で使用している QScrollBar オブジェクトにアクセスできます。理論上は、これらのスクロールバーの親ウィジェットを変更し、独自のレイアウトに組み込むことも可能ですが、これは非常に複雑で、QAbstractScrollArea の内部的なレイアウト管理と競合する可能性があり、Qtの標準的なアプローチではありません。

利点

  • 最大の制御
    スクロールバー自体の配置と振る舞いを完全に制御できます。

欠点

  • メンテナンス性
    コードの可読性とメンテナンス性が著しく低下します。
  • Qtの内部構造に依存
    Qtの将来のバージョンで内部実装が変更された場合、コードが壊れる可能性があります。
  • 非常に複雑
    QAbstractScrollArea のレイアウト管理を自分でほぼ完全にオーバーライドすることになるため、多くの手動での調整とコードが必要になります。

この方法は、ほとんどのユースケースでは推奨されません

QAbstractScrollArea::scrollBarWidgets() は特定の状況下で便利ですが、多くの場合、以下のガイドラインに従うと良いでしょう。

  • スクロールバーが交差する角に特定のウィジェットを配置したい場合は、setCornerWidget() がシンプルで効果的です。
  • スクロールエリアの機能とは独立したコントロール(例: ツールバー、ステータスバー、汎用的な操作ボタンなど)を配置したい場合は、QScrollArea を含むメインウィジェットを標準的なレイアウトマネージャー(QVBoxLayout, QHBoxLayoutなど)で構成するのが最も柔軟で推奨される方法です。
  • スクロールバーに密接に結合した小さな補助ウィジェット(例: ミニマップ、特定方向のボタンなど)で、QAbstractScrollArea の自動的なレイアウトに任せたい場合は、addScrollBarWidget()scrollBarWidgets() の組み合わせが最適です。