Expand QVBoxLayout horizontally to fill QScrollarea



  • Hi I'm having trouble with a layout issue with my QScrollArea (layouts are the trickiest things for me! :) I'd like the widgets contained in my scrollarea to fill the width of the scrollarea. I tried setWidgetResizable(bool resizable) but that resizes the vertical dimensions as well which I want to overflow vertically. The vertical aspect of the scrollarea overflows beyond the bottom of the scrollarea which is what I want. However the horizontal aspect stays at a fixed width such that it does not fill the whole area available in the scrollarea. A pic of the fixed width in the scroll area is below. I want the buttons and boxes to fill the available horizontal space. I omitted the rest of the code including a bunch of treewidgets for simplicity. Here is the code:
    What do I need to do for this to happen?
    Thanks

    QWidget *analyzeWidget = new QWidget;
    
        QHBoxLayout *buttonLayout = new QHBoxLayout;
        QPushButton *analyzeButton = new QPushButton;
        analyzeButton->setText("Start Backup");
        connect(analyzeButton,SIGNAL(clicked(bool)),this,SLOT(startAnalyzeBackup()));
        QCheckBox *showDatesCheckBox = new QCheckBox("Show Dates");
        showDatesCheckBox->setChecked(true);
        connect(showDatesCheckBox,SIGNAL(clicked(bool)),this,SLOT(showAnalyzeDates(bool)));
        QCheckBox *showSizesCheckBox = new QCheckBox("Show Sizes");
        showSizesCheckBox->setChecked(false);
        connect(showSizesCheckBox,SIGNAL(clicked(bool)),this,SLOT(showAnalyzeSizes(bool)));
        buttonLayout->addWidget(analyzeButton);
        buttonLayout->addWidget(showDatesCheckBox);
        buttonLayout->addWidget(showSizesCheckBox);
    
        QVBoxLayout *analyzeLayout = new QVBoxLayout;
        analyzeLayout->addLayout(buttonLayout);
        QWidget *analyzeScrollWidget = new QWidget;
        analyzeScrollWidget->setLayout(analyzeLayout);
        QScrollArea *scrollArea = new QScrollArea;
        scrollArea->setWidget(analyzeScrollWidget);
        QVBoxLayout *mainAnalyzeWidgetLayout = new QVBoxLayout;
        mainAnalyzeWidgetLayout->addWidget(scrollArea);
        analyzeWidget->setLayout(mainAnalyzeWidgetLayout);
        analyzeWidget->setWindowModality(Qt::ApplicationModal);
        analyzeWidget->resize(1000,750);
        analyzeWidget->show();
    
    
    
    

    0_1472765136445_scroll.png



  • To solve I did this:

    AnalyzeScrollArea *scrollArea = new AnalyzeScrollArea;
    scrollArea->setWidget(analyzeScrollWidget);
    analyzeLayout->setContentsMargins(0,0,0,0);
    analyzeScrollWidget->setFixedWidth(scrollArea->width()-scrollArea->verticalScrollBar()->width()-2);
    

    to set intial size then reimplemented resizeEvent in a subclass of QScrollArea:

    void AnalyzeScrollArea::resizeEvent(QResizeEvent *)
    {
        widget()->setFixedWidth(width()-verticalScrollBar()->width()-2);
    }
    

    donno if there's an easier way perhaps customizing the vertical layout inside the scrollarea



  • I wasn't able to see the image you mentioned in your post. Something odd with this forum perhaps or maybe something about my computer (?).

    Based on your description I have seen this problem before. My solution was to add the line you mentioned originally in your post ( setWidgetResizable(true) ). One thing I noticed is you don't have parent / child widgets so maybe this is a reason it doesn't work for you.

    This is a working example of something I use. It did compress the width when I first added this to the QScrollArea but it worked properly after setting the setWidgetResizable(true) option:

    	scroll_area = new QScrollArea(parent_widget);
    	scroll_area->setWidgetResizable(true);
    	
    	scroll_area_widget = new QWidget(parent_widget);
    	widget_layout = new QGridLayout(scroll_area_widget);
    	
    	utilities_icon_label = new QLabel(scroll_area_widget);
    	widget_layout->addWidget(utilities_icon_label, 0, 0, 11, 1);
    
    	transfer_label = new QLabel(scroll_area_widget);
    	widget_layout->addWidget(transfer_label, 0, 1, 1, 1);
    	
    	leitz_transfer_button = new QPushButton(scroll_area_widget);
    	widget_layout->addWidget(leitz_transfer_button, 0, 5, 1, 1);
    	
    	line1 = new QFrame(scroll_area_widget);
    	line1->setFrameShape(QFrame::HLine);
    	line1->setFrameShadow(QFrame::Sunken);		
    	widget_layout->addWidget(line1, 1, 1, 1, 5);
    	
    ... // lots more stuff ...
    
    	widget_vspacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
    	widget_layout->addItem(widget_vspacer, 20, 1, 1, 5);
    	
    	scroll_area->setWidget(scroll_area_widget);
    

    The vertical spacer at the bottom probably isn't needed (a leftover from the version before adding the QScrollArea).

    The QScrollArea is sensitive to the size hints from the child widgets. If you don't have a parent / child heiracy I assume getting the proper sizes is an issue.



  • Thanks. When I tried setWidgetResizable(true) it resized both vertical and horizontal dimensions so the vertical didn't overflow beyond the scrollarea which is what I wanted: horizontal to fill the scrollarea and vertical to go beyond. Did you get these results? Also doesn't QT automatically configure parent/child relationships?


  • Qt Champions 2016

    @Rondog said in Expand QVBoxLayout horizontally to fill QScrollarea:

    I wasn't able to see the image you mentioned in your post. Something odd with this forum perhaps or maybe something about my computer (?).

    Image upload to the forum is supposed to be turned off, sufficed to say it being active and accessible is a bug.



  • @Crag_Hack said in Expand QVBoxLayout horizontally to fill QScrollarea:

    Thanks. When I tried setWidgetResizable(true) it resized both vertical and horizontal dimensions so the vertical didn't overflow beyond the scrollarea which is what I wanted: horizontal to fill the scrollarea and vertical to go beyond. Did you get these results? ...

    Yes, this is what I got. This is what I wanted. In my example I had 20 rows of the QGridLayout filled in (I just showed a few lines as it wasn't necessary to post everything). The problem with the original program is that this forced the minimum size of my GUI so that it would accommodate this 'growing' widget. Using QScrollArea fixed this problem.

    I had a squished horizontal until I added the setWidgetResizable(true) option then everything worked perfectly.

    Also doesn't QT automatically configure parent/child relationships?

    I don't think it does this automatically (how can it?). You need to add the parents when constructing the children by adding it in the constructor:

    	scroll_area_widget = new QWidget(parent_widget);
    
    	utilities_icon_label = new QLabel(scroll_area_widget);
    	transfer_label = new QLabel(scroll_area_widget);
    

    When calculating the size of the widget it looks at the size hints of all the children. I suspect this is the reason you are having problems with QScrollArea (it has no idea what the ideal size of the scroll area widget should be).

    Another thing about parent / child widgets. If you create them independently you need to delete them. If you create a child widget of some other widget the children are deleted with the parent.



  • Do you mean you got the results I didn't want or did want? (I wanted vertical overflow and horizontal expansion to width of scrollarea)

    Also check this out from http://doc.qt.io/qt-5/layout.html

    Tips for Using Layouts
    
    When you use a layout, you do not need to pass a parent when constructing the child widgets. The layout will automatically reparent the widgets (using QWidget::setParent()) so that they are children of the widget on which the layout is installed.
    
    Note: Widgets in a layout are children of the widget on which the layout is installed, not of the layout itself. Widgets can only have other widgets as parent, not layouts.
    
    You can nest layouts using addLayout() on a layout; the inner layout then becomes a child of the layout it is inserted into.
    


  • @Crag_Hack said in Expand QVBoxLayout horizontally to fill QScrollarea:

    Do you mean you got the results I didn't want or did want? (I wanted vertical overflow and horizontal expansion to width of scrollarea)

    This is what I wanted as well. The width of the widget was the same as the width of the QScrollArea and the height of the widget was greater than that of QScrollArea (I would scroll this section vertically to see the entire widget with no horizontal scrolling).

    Another thing to watch for is horizontal and vertical spacers. Normally the size you set is not so critical but it can be if there is nothing to lock the total size. You can set this really small (I have used zero in some cases). A horizontal spacer that is set really wide might result in a horizontal scroll bar.

    I wasn't aware that layout's would re-parent widgets. I don't think I will rely on this but it is good to know.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.