Get size of QScrollArea viewport before showing - c++

I have a custom QDialog comprised of a QStackedWidget with QScrollArea widgets for each page of the stacked widget.
I want to set the size hint for the QDialog such that the dialog is just large enough that the scroll bars for the scroll area are not visible when the dialog is first shown (i.e. ensure size of QScrollArea viewport = size hint of child widget in scroll area). Currently, the default sizeHint() implementation for the QDialog has insufficient height, which causes the vertical scroll bar to be shown when first loaded.
I thought this could be achieved by re-implementing sizeHint() for the QDialog, whereby the size hint of the dialog would be adjusted by the amount required for the size of QScrollArea viewport to equal the size hint for child widget in the scroll area (for the first page of the stacked layout). Unfortunately, in sizeHint(), the size of the QScrollArea viewport is set to the default size of QStackedWidget (640x480), and only updates to the correct size once the QDialog is shown.
Is there some way to get the correct size of the QScrollArea viewport before it is shown, or another way to achieve the desired effect of adjusting the size hint of the dialog to prevent scroll bars from being shown when it is first displayed (aside from hard-coding the dialog size).

With the composition of your dialog as:
I have a custom QDialog comprised of a QStackedWidget with QScrollArea
widgets for each page of the stacked widget.
The tricky part is to answer:
Is there some way to get the correct size of the QScrollArea viewport
before it is shown?
Well, before switching to certain page you can estimate the scroll area viewport if it is either correctly set or you can just measure the content going inside the scrollarea. I usually force the widget to demand certain height from the scroll area like that:
wdgetInScrollArea->setMinimumSize( widgetInScrollArea->sizeHint() );
wdgetInScrollArea->adjustSize(); // sometimes it is needed
The the scroll area viewport hint is then more 'adequate':
qDebug() << scrollArea->viewPortSizeHint(); // report
I don't see the code but usually it is not even required to do any custom event handling here, just prepare all the nested widgets like that.

Related

Add widget next to qscrollbar

How do I place a widget next to a QScrollbar like here seen:
I use a QScrollArea and overwrite the Horizontal-QScrollBar. First I thought, I could use the paintEvent to draw a text like the "100 %" next to the bar. But I can only overwrite the existing painting.
Now I think, the only opportunity would be to implement the hole QScorllBarPrivate from the source code... anyone any idea?
The main idea is to create an overlay obscuring default horizontal scroll bar and displaing your own bottom line instead.
Create a widget representing the bottom line, i.e. a widget with labels displaying some information and a horizontal QScrollBar, all together put in a hbox layout.
Put this widget in the scroll area without adding it to a layout by making QScrollArea direct parent widget of this widget.
Use move() and resize() on the bottom line widget to position it properly on initialization. Also resize and reposition it on scroll area resize (you can use event filters or inheritance to get to resize events).
Make sure that scroll area's horizontalScrollBarPolicy is Qt::ScrollBarAlwaysOn so that scroll area's internal layout always keeps space enough for bottom line widget to fit in.
Also make sure that bottom line widget has the same height as default scroll bar. It should be easy as long as you remove spacing and margins in the hbox layout and labels (or other widgets) don't require more vertical space than a scroll bar.
Use horizontalScrollBar() to get scroll area's internal QScrollBar and syncronize it with your own bar. QScrollBar has rangeChanged() and valueChanged() signals so you can connect to them and update your bar properly. When user changes value of your scroll bar and triggers its valueChanged() signal, you should set the same value for the internal scrollbar. You can protect from infinite recursion in there by using a flag that indicates that this is your own change.

Preventing a QScrollArea from displaying a horizontal Scroll bar

I currently have the following structure in my form
I have a QFrame (Brown) that has a QScrollArea . Now Multiple QFrames are dynamically added to the QScrollArea (gray).The dynamically added QFrame are composed of a QLabel.
Now here is the problem I have disabled the horizontal scrollbar in the QScrollArea . Thus the horizontal scrollbar does not show up. The problem is that when the dynamically added QFrame (gray) is added to the the QScrollArea. Half of the frame is cut off. This is because I have no way to scroll horizontally. What I want is to have the dynamically added Qframe expand vertically instead of horizontally. Any suggestions ?
Update :
I have a QVBoxLayout inside the QScrollArea
Set the proper horizontal size policies for your dynamically created frames while creating them. One option is fixed size (QSizePolicy::Fixed), the other is QSizePolicy::Maximum (it's not very intuitive, but actually maximum means that the frame won't be bigger than the size specified by sizeHint() function). If you want the widget to expand vertically, set the vertical size policy to QSizePolicy::MinimumExpanding or QSizePolicy::Expanding - whatever works for you.

How to get QVBoxLayout to contract QDialog when removing child layouts?

I have a QDialog with a QVBoxLayout controlling its height.
This main QVBoxLayout consists of one or more QVBoxLayout children, followed by some other widgets. As I add additional QVBoxLayout children, (and/or lower widgets) the dialog box expands to accommodate them - as you would expect, and as I want.
However, when I remove QVBoxLayout children from the parent QVBoxLayout, the dialog box is not resized smaller by the amount equal to the size of the QVBoxLayout that was removed - it just remains the same size with unsightly large blank areas.
How do I achieve the correct dynamic behaviour in QVBoxLayout/QDialog, such that the dialog box is resized properly when child components are removed from the QVBoxLayout?
Make sure you call mainLayoutPtr->setSizeConstraint(QLayout::SetFixedSize) (this will also make the dialog not resizable by user, but it will be able to properly resize when widgets hide/show)
If you don't want to make the dialog non-resizable, you can resize it manually after any child is deleted:
QApplication::processEvents();
dialog->resize(dialog->sizeHint());
QWidget::adjustSize() is what you are looking for:
Adjusts the size of the widget to fit its contents.
This function uses sizeHint() if it is valid, i.e., the size hint's width and height are >= 0. Otherwise, it sets the size to the children rectangle that covers all child widgets (the union of all child widget rectangles).
For windows, the screen size is also taken into account. If the sizeHint() is less than (200, 100) and the size policy is expanding, the window will be at least (200, 100). The maximum size of a window is 2/3 of the screen's width and height.
Docs - http://doc.qt.digia.com/4.7/qwidget.html#adjustSize

QScrollArea widget is not expanding with a Flowlayout

I have a ui with a QScrollArea Widget. The QScrollArea uses a Flowlayout. My problem is when I add widgets to my layout the scroll area begins to scroll and does not expand when it has room to expand. I want the scroll area to expand to its limit before the scroll bar appears first.
How can I get the scroll area to expand before the scroll bar appears?
can you try doing setWidgetResizable(true) for your QScrollArea
ScrollArea->setWidgetResizable(true);
A couple of suggestions:
Ensure that the size policy of the scroll area itself is Expanding.
Set the "stretch" values of the size policy of the scroll area to a value greater than that of the other widgets in the same layout. Ie:
QSizePolicy policy = pScrollArea->sizePolicy()
policy.setVerticalStretch(1);
policy.setHorizontalStretch(1);
This assumes that the siblings of the scroll area (if any) have a stretch value of 0 (the default).
Subclass the scroll area and override the sizeHint() method.

Adding scroll bar to widget containing a layout in QT C++

I am new to QT and I am creating a widget that has a gridlayout. The gridlayout contains a matrix of QLineEdit widgets. The window resizes to fit the layout but when layout is large it goes off screen. When I maximize the screen, the QLineEdit widgets are resized to fit the screen and for large layouts they become extremely small.
I want to be able to resize the window without resizing the QLineEdit widgets and add scroll bars to navigate.
I tried the following with no luck:
Window->resize(QSize(500,500));
QScrollArea *scrollArea = new QScrollArea;
scrollArea->setWidget(Window);
where window is the widget containing the layout. Also, the window closes when after executing "scrollArea->setWidget(Window);" and I dont why.
If someone can help me out I would really appreciate it.
Thank You!
For disabling the vertical resize on the widgets, why don't you just use the setFixedHeight() method on the widgets?
For the menu bar, why don't you take it out of the widget that is scrollable. You can have a layout for the window that contains the menu bar and then the widget that contains everything else (scrollable part). Is that what you are looking for?
I fixed my problem by creating a QMainWindow with the menu bar. Then created a widget which includes the layout, set the Scroll Area to the widget. Finally set the central widget of the main widow to the scroll area.