How to make a Qt widget change its size? - qt

My problem probably is very simple, but I have no idea how to solve it.
So, I have several widgets in vertical layout. Some of them in some moment should be invisible. I suppose this moment the control that has expanding vertical policy should increase its height but it never happens. Why? How to force it to change the size? So far there is only one way to do that - to change the size of window manually a little bit and only after it the widget changes its height.

When you make a widget invisible (i.e. call hide), also remove it from the layout (see removeWidget). That way all of the other widgets will automatically resize to make use of the extra space. Since you are only hiding the widget, its space is still reserved in the vertical layout.
Make use of insertWidget to maintain the layout ordering when transitioning a hidden widget back into view. Otherwise, addWidget would always place it at the bottom. This approach should be less complex than managing the sizes manually.

Try calling adjustSize() on the parent of the layout.

Have you tried setting the stretch on 1 for the widget you want to be expanded when others are hidden?
QBoxLayout::addWidget( my_widget, 1 );
When this widget is added with a stretch of 1 and the other widgets without stretch, this widget will expand to the available space. Maybe that will do the trick.

Related

Having trouble resizing a QLabel in a QScrollArea

I'm trying to follow the example at the below link to have a picture (in a qlabel) shown in a scrollable area.
https://doc.qt.io/qt-5/qtwidgets-widgets-imageviewer-example.html
I'm using Qt Designer to make the ui instead of hardcoding everything. So I have a QLabel, in a QWidget (with a grid layout assigned to it), in a QScrollArea.
From the tutorial, they state the following for the sizepolicy of the QLabel:
We set imageLabel's [QLabel] size policy to ignored, making the users able to scale the image to whatever size they want when the Fit to Window option is turned on. Otherwise, the default size policy (preferred) will make scroll bars appear when the scroll area becomes smaller than the label's minimum size hint.
Setting it to ignored fits to the window, as expected and as stated. Setting it to preferred provides scroll bars when the image is larger than the scroll area, also as expected and as stated. My issue is that when the sizepolicy is set to preferred, the resize function of the QLabel doesn't work. It always stays at the default size of the loaded image. The only way that I'm able to get the resize function to work is when I don't assign a layout/break the layout to the widget in the QScrollArea, but then no scrollbars will appear when the image is larger than the QScrollArea.
Does anyone have any ideas of how to make the resize function and scrollbars work at the same time?
Thanks in advance for any help. I'm trying to learn qt5 still and this seems like it'd be a simple thing to do, but it's slowly driving me crazy.

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.

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.

qt unexpandable layout?

Ok, here is my problem:
I have a vertical layout which contains a QPlainTextEdit and a horizontal layout (containing 2 QPushButtons) below the text edit.
The vertical layout is just a part of GUI, and gets resized depending on screen resolution. Btw. it is a mobile app, so I don't have a lot of space on screen.
Push buttons have some text which is dynamically set, I don't know it from the beginning to code it manually.
My problem occurs when the text in push buttons is big, and my whole vertical layout is expanded to fit the buttons.
How can I make the vertical layout unexpandable? note, that this is different from "fixed" because of different screen resoulutions.
I'd just like the clip the buttons if they do not fit, but keep the layout width untouched.
Anyway to do this?
You'll need to set the maximum width for the buttons, not the layout, which is only widening to fit the wider buttons. Check out the docs on QPushButton and look for QWidget inherited functions called setMaximumSize or setMaximumWidth.
You can always GetWidth() on the button when it is an appropriate size, then setMaximumWidth using that value since you wouldn't ordinarily know this. Pick an appropriate default text size/val and use that to create your "dynamic" default since this is going on screens of varying size.

Qt QHboxLayout cell size ssues

For those of you who haven't been reading my Qt questoins, I am learning Qt for a project. I have only limited experience with GUI design at all, and not in Qt.
I've got a horizontal layout that I want to populate with some buttons. I can feed these buttons in just fine, but my formerly-square buttons are stretched horizontally to take up more space.
I want to let the layout manager determine the best way to size these buttons, but I also want their original proportions to remain intact. For instance, if I start would with 32X32 buttons that need to shrink to fit all of them in the layout, I want them to shrink proportionally so that the width to height scale is maintained. 20X20, 16X16, 12X12 would all be just fine, but 24X16 would be an example of dimensions that are unacceptable.
I've tinkered with size policies on the buttons and stretch options. I'm not seeing, even after reading the QPushButton and QHboxLayout classes how to do this. How is it accomplished?
Thanks.
As long as I understand the question correctly, I think what you want is QBoxLayout::addStretch(). This will add a spacer object that fills the unused space. So the buttons will have their ideal size and the spacer will fill the rest. You can try experimenting with this in Designer, it's easier than the write/compile/run cycle.
You should take a look at the answers to this question. This is a recap of my answer there.
You need to create a custom derivative of QLayoutItem, which overrides bool hasHeightForWidth() and int heightForWidth( int width ) to preserve the aspect ratio. You could either pass the button in and query it, or you could just set the ratio directly. You'll also need to make sure the widget() function returns a pointer to the proper button.
Once that is done, you can add a layout item to a layout in the same manner you would a widget. So when your button gets added, change it to use your custom layout item class.
I haven't actually tested any of this, so it is a theoretical solution at this point. I don't know of any way to do this solution through designer, if that was desired.

Resources