Fixing the size of layouts - qt

Is there a way to make the layoutStretch property always be obeyed? E.g. I have it set to "1,3,2", but then a widget (a label) in the first part (the "1" in "1,3,2") expands (when more text is added), and then the 1:3:2 ration is no longer respected. That is, the "1:3:2" ratio turns into something more like "3:1:3".

You should take a look at the property QWidget::sizePolicy. It controls how the layout respects the sizeHint() of its children when it updates the geometries.
So what you need to do is: Make the layout ignore the horizontal sizeHints of the child widgets by setting the horizontal sizePolicy of the three child widgets to QSizePolicy::Ignored:
QLabel *label = ...;
...
label->setSizePolicy(QSizePolicy::Ignored, label->sizePolicy().verticalPolicy());
(The second argument will ensure that the vertical policy isn't changed by this statement.
Of course, you should set the size policy of every child widget, this example code is only for the label.)
Note that the contents of your layout have to be widgets; I think nested layouts can't be assigned a size policy (but I might be wrong). At least using QtDesigner, there is no way of applying a size policy to a layout itself (if it isn't the layout of a widget). See comments for details.
In QtDesigner, you can set the sizePolicy of the child widgets like this:
Before:
Shrinked:
Select the items in the layout:
Set the horizontal size policy to "Ignored":
Result:

Related

Resizing Layout equal to MainWindow

When I run my program it will display all content properly, and when I resizing the main window, the layout along with all associated widgets remain fixed, rather than resizing with the main window. I used to increase my all widget and listWidget respect to window computer resolution size but still this not one work properly.
I used this one code finding the system height and width.
QWidget widget;
widget.resize(widget.width(), widget.minimumHeight());
QRect rec = QApplication::desktop()->screenGeometry();
int h = rec.height();
int w = rec.width();
// Increasing the listwidget size
ui->listWidget->setFixedHeight(h);
ui->listWidget->setFixedWidth(w);
//increasing the button size
ui->pushButton->setFixedHeight(h0.2);
ui->pushButton->setFixedWidth(w0.2);
At this link you will find two screenshots that illustrate my problem.
Please resolve to solve my problem. Thanks very much in advance.
When defining the layout of your windows and forms in Qt Designer you have to define each element of your form in advance, in order to have a working layout.
This solution is based on the screenshots provided in the comments to the question. Follow these steps:
Add an empty widget to the central area of your form, if there is nothing there. It will be used as a placeholder for the controls you will add later, and of course you can replace it with whatever widget you want. But you need it there to define a proper layout.
In the property panel, set the horizontal QSizePolicy of this widget to MinimumExpanding.
Add an horizontal spacer to the left side of your progress bar.
Define a minimum/maximum width for the white widget on the left (I guess it's a text area). As an example set the maximum width to 200
pixels.
Make the same for the QTabWidget on the right.
Give a minimum height to the Groupbox on top.
Then give the grid layout to the MainWindow.
You should get something similar in the designer view (I use a dark theme, yours will have different colors of course):
If you complete all steps you should have a nicely resizing window.
For the future: remember to integrally define your layouts, also using placeholder widgets when needed, read carefully the documentation about the widgets size policies (there are several, you need to play with them to fully understand each one) and keep in mind that Qt uses a container based approach which is different, as an example from those used by the .Net framework that relies on the concept of anchors.
EDIT : to answer questions in the comments
You will need to add a layout to any widget that contains other widgets, e.g. adding controls to your groupbox will require to give it a grid, horizontal or vertical layout in order to scale nicely on resize. Again use spacers and size policies to make it look the way you want. If you need to add or remove controls, or change their positions, you may need to brake the layout, rearrange and then set it again.
You can also select groups of widgets and give them a layout e.g. vertical, than another group and set them horizontal and so on... then give a grid layout to the container widget to build a compound layout.
There are endless possibilities, you just need to practice and go through trial and error as for everything else...
You can also do it all programmatically, check the Qt widgets documentation for this. But for complex layouts I would not go that way: it's a lot of code... and you have to compile and run to test every modification.
Using the QtCreator, within the designer you can simply right-click on the parent-widget and add a Grid-Layout.
This one resizes it's children to it's dimensions.

QSizePolicy true meaning, documentation and thoughts

I have been now two years working deeply with Qt layout system. After this time i encountered thosand of problems with SizePolicies and Layouts. I normally found out solutions, but never really understood what i was doing.
Now i was taking some time to try to understand correctly and build a 101 GUIDE for them and never fail. I found out this piece of information in the documentation about QSizePolicy of a QWidget:
This property holds the default layout behavior of the widget
If there is a QLayout that manages this widget's children, the size
policy specified by that layout is used. If there is no such QLayout,
the result of this function is used.
I thought that if you had a QLabel, for example, and you set the policies to Horizontal Expanding, Vertical Fixed, THE LABEL itself changed that way.
But it doesn't, at all.
When reading that i see that it talks about ITS CHILDREN inside the LAYOUT. So what does it mean, then?. Nothing is inside the label, is that why it does not work?.
WHat about inserting a label inside a QFrame, and telling the frame to be Expanding... Will the QFrame expand or stretch (depending on the rest of brother widgets in the same Layout) or will the label expand or stretch, not the QFrame?
What a mess...
What about Stretching?. If you set stretching 10 when you add the widget:
layout->addwidget(label, 10, Qt::AlignHCenter);
It doesn't work either.
Stretch 0 when you add the widget means : Take the policies i told you. Default, depends on the type of widget. Button-like widgets have expanding-fixed. Box-like Expanding-Expanding...
Stretch 10 means: grow maximum.
Am i right? Well. When having a QFrame and a QLabel inside, setting Expanding, and 10 to strech to the label DOES NOT WORK.
I don't understand all of your questions, so I will only answer to those that I think i do.
I thought that if you had a QLabel, for example, and you set the policies to Horizontal Expanding, Vertical Fixed, THE LABEL itself
changed that way. But it doesn't, at all.
I don't know what that means. What is the exact behavior you're expecting and what is actually happening? Is this label in a layout? Are there any other widgets in this layout?
WHat about inserting a label inside a QFrame, and telling the frame to be Expanding...
If you set a QSizePolicy to your QFrame object and set a layout to it, this size policy might be ignored. Docs: If there is a QLayout that manages this widget's children, the size policy specified by that layout is used. If there is no such QLayout, the result of this function is used. This means that the widget's layout should manage the size of the widget. Note that it will still respect the minimum/maximum width/height values.
Stretch 10 means: grow maximum.
What makes you think that?. The stretch factor is dependent on other widgets inside the layout. Docs: Stretch factors are used to change how much space widgets are given in proportion to one another.
When having a QFrame and a QLabel inside, setting Expanding, and 10 to strech to the label DOES NOT WORK.
Does not work how? If you set stretch for QFrame to 1 and for QLabel to 10, your QLabel object should always be 10 times as wide/high(depending of your layout type) as your QFrame object. If your QFrame has a layout and it contains children, then this might not work as it would depend on the childrens size policies.

Qt layout not expanding

I have a Qt Widget which has a frame, containg the rest of the widgets.
I only want one of the widgets to expand on maximazing the window, so I've set a max value for the others.
But it will only expand if I set a grid layout to the frame, which messes up the place of the widgets.
How can I solve it?
Do you use any kind of layout ?
Size policy only works if the parent has a layout set.
You can use a combination of different layouts to obtain the desired look, otherwise you will have to calculate the size of the 'expanding widget' yourself in the resize event method of the parent.

Make QTableWidget expand when dialog window size is changed

I have a QTableWidget, QTextEdit, and cancel & okay buttons.
I want these widgets to stay in the same position relative to each other, and the QTableWidget to expand if the dialog window is expanded or size changed...
How can I do that?
You need to look into Qt's layout system - using layouts will handle automatically resizing your objects based on the size of their parent.
A combination of using QWidget::setSizePolicy() and QBoxLayout::setStretch() (or more likely QBoxLayout::insertWidget(..., int stretch = 0, ...)) will allow you to acheive the behaviour you refer to where only certain objects expand to fill available space, while others remain a constant size.
Addressing the image you've given above as an example:
Aside from dragging and dropping objects into the form, to achieve this solution I have:
Set the vertical sizePolicy of textEdit to Fixed.
Set a height in textEdit's minimumSize for the sizePolicy to use.
Set layoutStretch in centralWidget to 1,0, i.e. assign the minimum possible space for the elements contained in horizontalLayout and give any remaining space to tableWidget.

How to set default height on QTableWidget

I have a widget which I'm putting in a QVBoxLayout. This widget's layout is a QVBoxLayout which includes a QTableWidget. When I display this everything is fine but the QTableWidget only shows a few rows. How can I set the height of the table to a decent value (like 20 rows) while still allowing the table to resize?
I've tried calling table.setMinimumHeight(200) but then the table can NEVER be smaller than 200. I've also tried setting the container widget height using setMinimumHeight but this has the same problem.
Check the sizePolicy for the QTableWidget. This will have horizontal and vertical size policies which, if I understand you correctly, should be set to "expanding" or "minimum expanding". There are a number of options and combinations for these and sometimes it can be tricky getting the right combination for all the widgets in your layout to get what you are looking for.
The size policies will work in combination with your min/max height/width settings and those of the other widgets in the layout.

Resources