Fixing sizes of widgets in QT designer layouts - qt

I have a QT form that has literally hundreds of widgets and to make them all fit on the screen at once (as required) I need to make them pretty small. The Form will have fixed (non resizable) size when used. I can resize the widgets to the desired height/width and use the appropriate (small) font size, make their size policy "fixed" etc. However, as soon as I start putting them into layouts, they gow to some, much larger minimum size. This is particularly true for the height of the widgets, but width is sometimes affectged as well.
My problem would be solved if I knew how to do one of the three following things:
Change a layout's default minimum size(s) for widgets.
Force a layout not to alter widgets sizes.
Use Qt designer to nicely align widgets in grid-like formats without using layouts.
I searched extensively Qt designer's docs and SO, to no avail.
Help is greatly appreciated

Use layouts with QWidget::setFixedSize in code (or alternative you can set the fixed size policy for each widget in designer) or you can use QLayout::setSizeConstraint

Related

Move splitters in design mode

When i add splitters, it acts as a layout, but also allows to resize the widgets in runtime. So, for example, i managed to lay out my widgets in this way:
Therefore, i can resize my widgets in runtime. As i noticed, this function is also available in designer mode, but it doesn't work properly. I tried to hover over my splitter and drag it in designer mode, but it only replaces the entire widget.
That is how does my main window look like in QtDesigner. I haven't tried to code yet. The problem is, that even though i used to set a stretch factor, my widegt's look in designer mode and in runtime completely differ. They have another sizes.
So, what are the problems:
Firstly, i can't change my widgets sizes properly, using stretch factors. I don't know, i tried to change size policies, but i did't manage to see an effect. I have somehow changed size of the vertically oriented widgets, but when speak about horizontal orientation - stretch factor and size policy doesn't change anything at all.
Secondly, i can't move my splitter in designer mode. It's position is constant, by default, it's always somewhere in the middle.
Thirdly, i have bugs (i think so) with my widget sizes in designer mode. They differ with widget's sizes in runtime.
Question:
So, how can i change widget's sizes properly? Maybe there's a way of moving a splitter in designer mode - do newer versions of Qt have it? Currently i'm using Qt 5.9.9. Also, why these bugs, and are they bugs at all. Maybe i just should update my Qt to newer versions to get access to newer functionalities?
Comment: I'm not sure if stretch factors work with layout as they do with widgets. I'm using layouts exactly the same way i use widgets. My layout's wrong(maybe) use may have caused this problem. Anyways, i'm entirely new to Qt, and may not know something to understand it completely.

How to properly size Qt widgets?

Main Question
What is the "right" way to give your widgets default sizes and make sure they contract, expand, or remain fixed if there is additional or not enough space to accommodate them?
How I Think Qt Works
After reading the Qt documentation it seems like the sizing algorithm goes something like this...the layout begins by asking its children for their ideal size via the QWidget::sizeHint method. If the layout has additional space or not enough space then it'll determine which widgets to resize based on each widget's sizing policy (QWidget::sizePolicy), minimum size (QWidget::minimumSize), and maximum size (QWidget::maximumSize).
Why isn't there a QWidget::setSizeHint method?
If my understanding is close to being accurate then it would seem all you'd have to do is set the sizeHint, sizePolicy, maximumSize, and minimumSize on each widget and everything would just work. So why isn't there a setSizeHint method?!?!??!! Sure, every time you use a widget that provides all of the functionality you need (QTableView, QComboBox, etc) you could extend it and override a single method but that sounds absolutely ridiculous.
One of the sizing issues I'm fighting with.
I've got a QMainWindow with a QDockWidget on the left hand side. The QDockWidget has a QTableView. I'd like to have the QDockWidget/QTableView take up a "reasonable" amount of space on start up and then the user can resize it however small or large they'd like.
Unfortunately, when the application starts up it gives the QDockWidget/QTableView so little space that it requires a horizontal scroll bar. The only way I've found to force it to give it a reasonable amount of width is to set the QDockWidget's minimum width but then it prevents the user from resizing it as small as they might like to.
Why isn't there a QWidget::setSizeHint method?
In my opinion it is much better for a widget to compute its preferred size based on its content (or rules) instead of allowing the coder to set a sizeHint probably hardcoded or at least prone to errors.
I almost never had to set a size on a widget, playing with the QSizePolicy was enough. And when I needed some specific constraints, playing with minimum/maximum sizes was enough. So that Qt layouts were always able to adapt the widget.
If you want to set up yourself some percentages on the sizes etc, you can play with the stretch parameter. You can also add spacers when you need empty spaces.
Extending a QWidget to override the QWidget::sizeHint method does not sound ridiculous to me, as you change the widget behaviour by changing its preferred size and that fits the polymorphism spirit of OOD.
How to properly size Qt widgets? is a vague question and depends on the use cases. Most of the time choosing the good layouts and size-policy lets you achieve very adaptative GUI. Qt Designer can help to do this right, even if the layout management is not always intuitive (you need to place your widgets first and then set them in layouts from the inner to the outer layout).
About your specific issue, it's hard to tell why your QDockWidget gets too small without knowing the details of the layout(s) you have around your two widgets in the window. Maybe it is a specific issue with QDockWidget : see related questions :
QDockWidget starting size
Qt 5.7 QDockWidget default size
Prevent QDockWidget autosizing behaviour

QSplitter Stretching Factors behave differnt from normal ones

I want to create a flexible layout, where the User can resize Widgets, but still give a good default layout. I'm using the Qt Designer for everything.
As a minimal example I used a simple Windows with a Widget and a plainTextEdit. The later one seems to cause the problems, which is why I choose it. At first I built it without the Splitter which worked just fine. The Stretching factors are 1:1 by the way.
Now I put both widgets in a Splitter (by breaking the main layout, putting both widgets in a Splitter and setting a new layout to the main widget). Resizing still works but the stretching factors behave weird:
The PlainTextEdit seems to take up far to much space. The Stretching Factors are still at 1:1. I found a workaournd, by changing the stretching of the upper widget to a much higher value (in this case 9:1), which looks good again:
So my question is: Why do the stretching factors begin to behave weird when I put the images in a Splitter? And how can I solve this without using arbitrary guessed stretching factors?
QSplitter::setSizes() can be used to set relative sizes. According to the documentation, "any additional/missing space is distributed amongst the widgets according to the relative weight of the sizes".
In this case, it is a bit ugly, since you have to add this in your code rather than editing your layout in QDesigner (normally, you would want to define your layout only at one place), but still it is quick and works:
MyWindow::MyWindow(QWidget* parent):
QWidget(parent)
{
m_Ui.setupUi(this);
m_Ui.splitter->setSizes({2000, 1000, 1000});
However, I had to use big numbers (instead of {2, 1, 1}), maybe because at this point, the window is not completely set up yet (apparently, Qt is not a big fan of RAII...). Also, this kind of notation works probably only with a recent C++ version, otherwise you can also define the QList in some extra lines.

Resolution handling in QMainWindow

I've a QMainWwindow, and I've fixed its size.
i.e. I've set Minimum and maximum size of the window to the same number.
Could anyone tell me whether this will be a problem if I'm to use this in another screen with a different resolution, and if so, how am I to handle it?
Kindly advise, and also if there's another way ( perhaps more elegant) to set the size of the QMainWindow.
UPDATE :
I have a QMainWindow with a QTableView as a widget, amongst others. When I expand the main Window, the tableview does not, and it leaves an ungainly blank space, so I fixed the size.
If I were to make it resizeable, how do I expand the QTableView widget, alongwith the QMainWindow. I have a Central Widget, this widget has a vertical box layout, and to this layout I've added the 3 widgets, one with QGridlayout, one horizontal line, and the other QTableView. The QTableView, on its own, is not inside a layout.
I'd imagined this would be sufficient to expand the table too, once QMainWindow were expanded, or reduced, but it doesn't happen.
How do i go about it, i.e., expanding the QTableView as well?
Thanks.
It will be a problem if you fix the size to one that is larger than the screen can handle. There are various ways to scale the size of a window according to the screen size. I recommend using QApplication::desktop(), which will return the desktop widget (you may need to #include <QDesktopWidget>. Note that this widget can actually encompass multiple screens, so if you just want the current screen, you can just do:
QRect screenGeometry = QApplication::desktop()->screenGeometry();
You could alternatively use QDesktopWidget::availableGeometry().
It is worth mentioning that among Qt users, I think there is a general dislike of fixed size windows. Most recommend taking full advantage of the Qt layout system, which provides lots of flexibility for resizing windows. I'm not saying you should definitely do this, because all projects are different, but it could be worth looking into.

Understanding form layout mechanisms in Qt

Qt has a flexible and powerful layout mechanism to handle view of desktop application's windows.
But it is so flexible, that it nearly cannot be understood, when something goes wrong and needs fine tuning. And so powerful, that it can beat anyone in their tries to overwhelm Qt's opinion of how form should look.
So, can anyone explain, or provide articles, or source of Qt's positioning mechanisms?
I'm trying to force the QLabel, QPushButton and QTableView, marked by trailing underscores in their names, be two times higher than QTextBrowser having verticalStretch = 1 below. How can I handle widget's height properly?
.ui file of my form on google docs. Search '____' in names, preview in QtDesigner
Layouts are actually easy to understand "I think". :)
A simple explanation of layouts can be found in the QT book "C++ Gui programming with QT 2nd edition"
What you should be aware of regarding layouts and their size policies
Most Qt widgets have a size policy. This size policy tells the system how the widget should stretch or shrink. It's got from the class QSizePolicy. A size policy has both vertical and horizontal components.
Most widgets also have a size Hint. This size hint tells the system a widgets preferred size
QSizePolicy has a stretch factor to allow widgets to grow at different rates
**I am only familiar with 4 size policies**
fixed size policy - The size of the widget is fixed and it can't be stretched. It remains at its size hint.
minimum size policy - The size hint is the smallest possible size of the widget, but it _can still_ grow bigger if necessary.
Preferred size policy - the widget can shrink or grow bigger than its size hint.
expanding size policy - the widget can shrink or grow bigger than its size hint :)
You may want to ask,
What is the difference between preferred and expanding?
**Answer:** Imagine a form with 2 widgets, one with preferred and another with expanding. Then any extra space will be given to the widget with the expanding policy. The widget with the preferred policy will remain at its size hint.
I recommend (WARNING: am not an expert :)) you buy and read through "C++ Gui programming with QT 2nd edition". I am currently reading it and it is making a lot of sense. Look at the images and see if they make some sense.
Explaining size policies
A simple example
This is a simple dialog with 2 buttons whose horizontal and vertical size policies are shown as are the horizontal and vertical stretch.
Here is the preview at its smallest size.
Here is another preview at a larger size
[EDITED: //added size hint example]
WHY YOU SHOULD CARE ABOUT SIZEHINT
You can see that every widget has a sizeHint which is vital because QT's layout system always respects the sizeHint. This is only a problem if the default size of the widget is not exactly what you want. The only way around this problem is to extend (subclass) the widget and reimplement its sizeHint() member function. An example is worth 1000 words. To save space, see my blog where there is an example project.
According to its docs:
When you add widgets to a layout, the layout process works as follows:
All the widgets will initially be allocated an amount of space in accordance with their QWidget::sizePolicy() and QWidget::sizeHint().
If any of the widgets have stretch factors set, with a value greater than zero, then they are allocated space in proportion to their stretch factor (explained below).
If any of the widgets have stretch factors set to zero they will only get more space if no other widgets want the space. Of these, space is allocated to widgets with an Expanding size policy first.
Any widgets that are allocated less space than their minimum size (or minimum size hint if no minimum size is specified) are allocated this minimum size they require. (Widgets don't have to have a minimum size or minimum size hint in which case the stretch factor is their determining factor.)
Any widgets that are allocated more space than their maximum size are allocated the maximum size space they require. (Widgets do not have to have a maximum size in which case the stretch factor is their determining factor.)
And sizeHint() is the recommended size of a QWidget, and the Layout of the widget parent will take sizeHint() and sizePolicy() into consideration to determine the space of the child widget can hold.
You can use QT Style Sheets to control the widgets height
and other properties in an easy customizable way.
http://doc.qt.io/archives/qt-4.7/stylesheet.html
As for the layouts you need to use them wisely and strongly
coupled with spacers in order to make the widgets behave
exactly the way you want them to.
http://doc.qt.io/archives/qt-4.7/designer-layouts.html

Resources