Make QTableWidget expand when dialog window size is changed - qt

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.

Related

Layout management in Qt

I have a small program which contains a QGroupBox with other widgets like this:
I tried many ways to manage the size of the QGroupBox to make the height as the same as the rest of the parts. Except for the way of using setMaximumHeight, because I want the size to change dynamically with the window size too. what else can I do to manage the layout?
Right now there are three items in a layout. The layout will try to fill the available space. QLineEdit and QSpinBox (or whatever your second widget is) have SizePolicy.vertical == fixed, so all extra space goes to the QGroupBox.
You have these choices:
Add a vertical spacer as fourth item below the groupbox to your layout.
Set maximum height of your groupbox - then the remaining space will be evenly spaced between the items.
Adjust the size of your window / widget / dialog (in Qt Designer or via code).

Qt layouting: default size constraints vertically, setFixedSize horizontally

I'm developing an app with a complex hierarchy of widgets and layouts, but in short it has a central widget with a formulary as upper widget and a QScrollArea as buttom widget (by means of a QVBoxLayout).
That QScrollArea represents a list (grid layout indeed) of QPushButtons which can contain a huge number of buttons (or not).
I want my app fits the following constraints:
Both (form and list) consume all available horizontal space, redistributing its contents to fill all horizontal space (nor SpaceItems neither contents margins).
Both must save as vertical space as possible, in order to make "lines" close to each other.
I've solve partially my problem making use of setSizeConstraint(QLayout::SetFixedSize) on the form, which shrinks it vertically, but also horizontally, causing that both, list and form, have different widths, wich doesn't look like very well.
How can I achieve that? I mean, how can specify something like grow horizontally to fill the widget but shrink vertically has much as possible?
Add a spacer as the last item to the layout:
gridLayout->addItem(new QSpacerItem(10, 10, QSizePolicy::Expanding, QSizePolicy::Expanding), lastrow, 0);
I think this is what you want:
If you know how many columns you will have (and it doesn't change), insertStretch() in the last column (although it might give you the same effect as using a spacer).
int columnCount = gridLayout()->columnCount();
gridLayout->insertStretch( columnCount(), 1 ); // Default stretch for other
Note that this will resize your buttons to the size Qt thinks they should be unless you are explicitly changing their widths.

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 is larger than it should be

I had a layout all nicely designed in Qt, but as soon as I clicked on the parent window and set it to a grid layout, things got all wonky. I've read every tutorial I can find as well as the Qt designer manual and just cannot figure out why this is happening. I have attached a screenshot to show the problem:
As you can see, the vertical layout on the left insists on being wider than the children it contains. Both the label and the treeview are set to sizePolicy maximum, and the maximum width is set to 260px. The children themselves stay the correct size, but the vertical layout that contains them doesn't.
The vertical layout in the middle is set to expanding, and the one on the far right is setup the same as the one on the left, only that one appears to work. How do I make the first vertical layout conform to it's children's width?
Also, if I may sneak a second question in, I have a QTextEdit inside the tab widget in the lower right, but it will not fill to take up the space of the full tab view. You can't see that in the screenshot, but if I pull the tabview up, the textedit within it doesn't stretch with it. How do I make it conform to the size of the tab? It's already set to sizePolicy expanding, but that doesn't seem to help.
The problem is most likely that you need to experiment with "stretching" the layout. Stretch sets the size of layout cells in relation to each other. The default is 0, which means no stretching occurs.
In your case, I believe you want to set the stretch of the first column (column 0) to 0, and the stretch of the second and third columns to 1. This means that the first column will always be as small as possible, and the second and third columns will try to be equally wide.
You can set the stretch programmatically quite easily; for example, to set the first column to stretch 0:
layout->setColumnStretch(0, 0);
In Qt Designer you can access column and row stretches as any normal properties.

QT Layout - initial directions

I am new to QT. I'm trying to understand the layout mechanism by trying to implement this small window seen below. It has the following elements under the QWidget that's the main window:
One big QWidget that stretches on all the client area.
Two QWidget containers on the top of the window. Both should have the same height, but the right one stretches horizontally, as the window grows/shrinks.
one button container widget on the top right, with fixed height and width
Large QWidget container filling the rest of the client area, that should resize as the window resizes.
The parent window itself is resizeable.
I'm looking for hints as to what layout I should use. How do I achieve this programatically? define what stretches automatically, what stays with a fix size? and how the proportions are kept where they need to be kept.
I'd appreciate any pointer you may have.
The easiest, and IMHO best, way to accomplish this is via the QHBoxLayout and QVBoxLayouts. You can do this via the designer in QtCreator, but I find it doesn't work perfectly if you need to adapt things over time. If it's a static set of widgets, I do suggest designing it using the QtCreator designer as it'll greatly simplify your life.
If you're going to do it programatically, the main window should be set to use a QVBoxLayout and then two sub-QVBoxLayout's after that, where the bottom one is configured to take any space it can get. Then in the top QVBoxLayout, add a QHBoxLayout with your two upper components.
to set a widget to fixed size in code you call setFixedSize( int h, int w ) on the widget. To do it in Designer click on the widget and look in the property editor in the QWidget section. open the sizePolicy thingy and set horizontal and/or vertical to fixed. Then open Geometry and set the width and Height.
To make them stretch at different ratios in code you use a separate argument when using a box layout. eg layout->addWidget( button1, 1 ); layout->addWidget (button2, 2); this would cause button2 to expand at twice the rate of button1. To do this in designer, open the sizePolicy property of the widgets and set the HorizontalStrech and/or VerticalSretch. Note that the size policy needs to not be Fixed in this case for the direction you want to set the stretch on. Also it will never let a widget shrink below its minimum size (it would rather mess up the ratio than shrink something too small).

Resources