Preventing a QScrollArea from displaying a horizontal Scroll bar - c++

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.

Related

Setting minimum fixed size QCustomPlot bar graph inside QSplitter

I am using QCustomPlot to plot a bar graph. There are two such bar graphs horizontally arranged inside a QSplitter (which can be dragged). On dragging the splitter horizontally, the bar graphs resize and scale to the point that the axes labels start to overlap. I have a parent QWidget which contains a QScrollArea which ultimately contains the plot. This widget is added to the QSplitter.
QWidget* topLeftParent = new QWidget;
topLeftParent->setLayout(new QVBoxLayout);
QScrollArea *topLeftScrollArea = new QScrollArea(this);
topLeftScrollArea->setWidget(energyGraph->GetPlot());
topLeftScrollArea->setWidgetResizable(true);
topLeftScrollArea->setFrameShape(QFrame::NoFrame);
topLeftParent->layout()->addWidget(topLeftScrollArea);
m_pTopLeftHorizontalSplitter->setMinimumWidth(500);
m_pTopLeftHorizontalSplitter->addWidget(topLeftParent);
Existing Behaviour:
On dragging the splitter horizontally, the bar graphs expand/shrink horizontally till the axes tick labels overlap and ultimately at a very small value of width, the horizontal scrollbar appears, which is useless. Same is the case for resizing the window as well.
Required Behavior
However, I seek a different behavior. I want the bar graphs to be horizontally scrollable without them resizing on dragging the splitter i.e. dragging the splitter left/right should reveal more/less of the graphs, and not resize them
Queries
How do I specify that the bar graph should have a minimum size and expand from that depending on the number of ticks on x-axis?
How do I stop the plot from automatically expanding/shrinking?
What I have tried so far
I have tried setting minimum size for the plot, but it does not work.
I have also tried specifying the stretch factor for the splitter to 0, but that also has no effect i.e. the behavior is auto resizing bar graphs in both the cases with scrollbar appearing too late.
To achieve the required behavior you can use the QTableWidget widget. You need to:
Create a QTableWidget widget with two columns and and one row.
Set the QScrollArea widget as the parent of the QTableWidget widget.
Hide the horizontal and vertical headers. To do so set horizontalHeaderVisible and verticalHeaderVisible to false.
Add QCustomPlot widgets into the table using the setCellWidget(int row, int column, QWidget * widget) method.
This is how it was solved: I just had to call the setWidgetResizable with false for the scroll area and now I have a permanent scrollbar and the custom plot does not resize while dragging the splitter.
Find if you have this line:
ui->my_plot->setInteractions(QCP::iRangeZoom | QCP::iRangeDrag);
And edit it to whatever you want, for example just range zoom:
ui->my_plot->setInteractions(QCP::iRangeZoom);

Adding scroll bar to a Qwidget

I want to add scroll bars to the frame container. the QscrollArea can only take on widget but in my frame I need many wigets
I tried to write a code for the bars after adding a horizantal and vertical one but It's too hard.Is there any pre-made free code I could use ?
thank you
QScrollArea can take any number of widgets - indirectly. The widget() can contain any number of child widgets, it can have a layout set, etc. See e.g. this answer.

Get size of QScrollArea viewport before showing

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.

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.

Reserving Space for QScrollArea

I am using a QScrollArea with a custom QWidget. The problem I am facing is that whenever the scrollbar appears, it leads to shifting of elements in the widget. So, I want to reserve some space, so when the scrollbar appears or disappears, the widget is not affected. How can I achieve this?
scrollArea->setWidgetResizable(false);
I encountered this problem and just solved it(might not completely).
I set a fixed width for scroll widget and QScrollArea, and set QScrollArea Horizontal SizePolicy fixed, and hide HorizontalScrollBar.
Sample code
QWidget *pWidget = new QWidget(this);
pWidget->setFixedWidth(500);
pWidget->setLayout(...)
QScrollArea *pScrollArea = new QScrollArea();
// Same with widget
pScrollArea->setFixedWidth(500);
pScrollArea->setWidget(pWidget);
pScrollArea->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
// Needed.
pScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
I also find a Bugreport: QTBUG-2347
QScrollArea: a new scroll policy that reserves space for the scroll bar, and it is closed. But I don't know whether the bug is fixed and what's the solution.