Search code examples
c++qt5qwidgetqscrollareaqlayout

Custom widgets in scroll area not respecting minimum?


I'm getting closer to getting a QScrollArea working, but it's still shrinking my custom widgets as they are added. Everything is resizing fluidly, and if the scroll area is too small, then the scroll bar appears, so it clearly has some idea of a minimum size.

At start, with two custom widgets in the scroll area, you can see some shrinking:

screenshot - widgets are being shrunk

Here's the same window below the critical point. The text is now completely gone, but it won't shrink the QLineEdit, so it finally adds a scrollbar. (the scroll area has a blue background, the content widget is the purple)

enter image description here

I started in Design, but everything below the scroll area's widget is in code, as I was having trouble getting the vertical layout to work right using design.

Here's the starting point:

screenshot of design

There's a page in a StackWidget that has two elements in a vertical layout. The scroll area has a QWidget. The constructor for MainWindow defines a vertical layout, assigning it to the member scrollWidgetLayout, and giving that layout to the scroll area's widget:

scrollWidgetLayout = new QVBoxLayout(ui->scrollAreaWidgetContents);
ui->scrollAreaWidgetContents->setLayout(scrollWidgetLayout);

The app starts on the first page of the stack widget, the user logs in, and the app runs off to fetch records from the server. Each record is turned into a widget:

RecordFolderWidget::RecordFolderWidget(Record *r, QWidget *parent) : QWidget(parent)
{
    record = r;
    //setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);

    QGridLayout *layout = new QGridLayout();
    pathLineEdit = new QLineEdit();
    finderButton = new QPushButton("...");
    QLabel *nameLabel = new QLabel(record->name);
    layout->setSpacing(5);
    layout->setMargin(3);
    layout->addWidget(nameLabel, 0, 0, 0, 1, Qt::AlignCenter);
    layout->addWidget(pathLineEdit, 1, 0);
    layout->addWidget(finderButton, 1, 1);
    setLayout(layout);
    //setMinimumHeight(sizeHint().height());
}

Note that there are some lines commented out, these are things I have been playing with to try to get it to work. The sizeHint, btw, appears to be correct, and does not change.

Once that Widget is created, it gets added to the scroll area's widget:

    RecordFolderWidget *rf = new RecordFolderWidget(record);
    rf->setParent(ui->scrollAreaWidgetContents);

    scrollWidgetLayout->addWidget(rf);

I tried here to also resize the scroll areas contents, with no luck:

ui->scrollAreaWidgetContents->resize(rfSize.width(), rfSize.height() * records.count());

where rfSize was pulled from the custom widget's sizeHint after it was created, and this line was called once after the loop to create/add all of the widgets.

Other than the setMinimumHeight and resize above, I've tried changing the SizePolicy for the scrollAreaWidgetContents from preferred to expanding to minimumexpanding and did not see any difference. I'm sure I've missed something trivial, but just can't find it.


Solution

  • The problem that I see in your code is when adding the QLabel you are setting the rowSpan to 0, I have changed it and I can observe it correctly. In the next part I show my test code and the result:

    QVBoxLayout *scrollWidgetLayout = new QVBoxLayout(ui->scrollAreaWidgetContents);
    
    for(int i=0; i<10; i++){
        QWidget *widget = new QWidget;
        QGridLayout *layout = new QGridLayout(widget);
        QLineEdit *pathLineEdit = new QLineEdit;
        QPushButton *finderButton = new QPushButton("...");
        QLabel *nameLabel = new QLabel(QString("name %1").arg(i));
        layout->setSpacing(5);
        layout->setMargin(3);
        layout->addWidget(nameLabel, 0, 0, 1, 1, Qt::AlignCenter);
        layout->addWidget(pathLineEdit, 1, 0);
        layout->addWidget(finderButton, 1, 1);
    
        scrollWidgetLayout->addWidget(widget);
    }
    

    enter image description here