I have used a scroll area for something similar. I setup mine a little different. I use widgets to contain each child item (not layouts)
// constructor of parent widget
scroll_area = new QScrollArea(this);
scroll_area->setWidgetResizable(true);
parent_widget_layout->addWidget(scroll_area);
d_scroll_area_widget = new QWidget();
scroll_area->setWidget(d_scroll_area_widget);
d_scroll_area_layout = new QVBoxLayout(d_scroll_area_widget);
// see note below for explanation of spacer
d_bottom_vertical_spacer = new QSpacerItem(100, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
d_scroll_area_layout->addItem(d_bottom_vertical_spacer);
Too add items
d_scroll_area_layout->removeItem(d_bottom_vertical_spacer);
...
d_scroll_area_layout->addWidget(new_widget_item);
d_scroll_area_layout->addItem(d_bottom_vertical_spacer);
The bottom spacer is to make sure that if there is only one child widget of the scroll area it is not resized to fill all the available space. The bottom spacer is always moved to the bottom.
Removing items is a bit more tougher. Actually, in my implementation, I don't. I hide the ones I want to remove and re-assign them if they are re-used in the future. In my case it works for what I need it to do but it may not be practical if you have something where you want to insert / delete / move items.
As @SGaist mentioned you can use a QListView/QListWidget. The items do not need to be the same size and they can be resized after the fact if more or less information is displayed which changes the size.
// Constructor
d_ReportListView = new TListView; // subclass of QListWidget
d_ReportListView->setDragEnabled(true);
d_ReportListView->setDragDropMode(QAbstractItemView::InternalMove);
d_ReportListView->setSelectionMode(QAbstractItemView::ExtendedSelection);
d_ReportListView->setAutoScroll(true);
d_ReportListView->setAutoScrollMargin(48);
d_ReportListView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
d_ReportListView->setUniformItemSizes(false);
d_ReportListView->setResizeMode(QListView::Adjust);
// important function to enable resizing QListWidgetItems
// if a list widget item size is changed update the size hits of that item
void TListView::UpdateSizeHints(void)
{
TListViewItem *LVItem;
QSize ItemSize;
int LineHeight;
LineHeight = TListViewItem::LineHeight(); // fixed line height
ItemSize = this->size(); // size of parent
ItemSize.setHeight(num_lines * LineHeight); // only adjusting height to fit required lines
// LVItem = pointer to current QListWidgetItem that need to be set or changed
LVItem->setSizeHint(ItemSize);
}