Введите: базовый код. Создает 25 QPushButtons
, завернутый в QWidget
с QVBoxLayout
, который (QWidget
) сам по себе является единственным дочерним элементом top-QVBoxLayout, который обрабатывает размещение виджета в нашем верхнем scroll_area_test-QWidget
. Вторая обертка QWidget
может показаться излишней, но она пригодится позже.
#include <QVBoxLayout>
#include <QScrollArea>
#include <QWidget>
#include <QPushButton>
#include <QApplication>
/*
* This declaration actually lives in its own header file,
* but for simplicity's sake this code includes it here directly.
*/
class scroll_area_test : public QWidget {
Q_OBJECT
public:
scroll_area_test ();
};
scroll_area_test::scroll_area_test () {
QVBoxLayout *top_layout = new QVBoxLayout (this);
QWidget *contents = new QWidget (this);
top_layout->addWidget (contents);
QVBoxLayout* inner_layout = new QVBoxLayout (contents);
for (size_t i = 0; i < 25; ++i) {
QPushButton *tmp_button = new QPushButton (this);
inner_layout->addWidget (tmp_button);
}
}
int main (int argc, char **argv) {
QApplication app (argc, argv);
scroll_area_test widget;
widget.show();
return (app.exec ());
}
Это прекрасно работает. Он создает окно с 25 кнопками, спрятанными друг над другом. Учитывая, что разрешение моего экрана достаточно высокое, я могу видеть все окно. Все денди.
Но подождите, а что, если разрешение пользователя было ниже моего? Окно было бы слишком большим, чтобы поместиться на их экранах! Увы, для таких ситуаций есть решение. Введите: QScrollArea
.
scroll_area_test::scroll_area_test () {
QVBoxLayout *top_layout = new QVBoxLayout (this);
QScrollArea *scrolling_area = new QScrollArea (this);
scrolling_area->setWidgetResizable (true);
scrolling_area->setFocusPolicy (Qt::NoFocus);
top_layout->addWidget (scrolling_area);
QWidget *contents = new QWidget (this);
//contents->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
QVBoxLayout* inner_layout = new QVBoxLayout (contents);
//inner_layout->setSizeConstraint (QLayout::SetMinimumSize);
for (size_t i = 0; i < 25; ++i) {
QPushButton *tmp_button = new QPushButton (this);
inner_layout->addWidget (tmp_button);
}
scrolling_area->setWidget (contents);
}
Я ожидаю, что это не изменит макет в моей системе, поскольку места достаточно для отображения всех виджетов.
Однако это новый вывод:
Что я делаю неправильно? Я хочу, чтобы область прокрутки автоматически изменялась до размера своего дочернего элемента (отсюда setWidgetResizable (true)
), ограниченного максимальным размером окна. Кажется, здесь это не так. Размер содержащего виджета не учитывается правильно, и поэтому область прокрутки а) меньше по высоте, чем должна быть, и б) больше по ширине, чем должна быть, и то, и другое по сравнению с внешним видом без переноса QWidget
в QScrollArea
.
Я уже поиграл с ограничениями размера и политиками (показаны закомментированным кодом), но визуально это ничего не изменило.
N.B.: Я столкнулся с этой проблемой в гораздо более сложной ситуации, но смог абстрагироваться от этого примера.