I'm trying to place a text label next to a spin box in a horizontal layout. I want the label to be as small as possible, and the spin box as large as possible, so I set the label's horizontal sizing policy to Minimum and the spin box's horizontal sizing policy to Maximum. However, This results in the label having the maximum size and the spin box having the minimum size:
If I swap the sizing policies, I get what I want:
Is this backwards behavior a known bug, or am I just not understanding something about Qt layouts?
Using QtCreator 2.7.0 based on Qt 5.0.2 (32-bit) on 64-bit Windows 7.
"minimum" means that the widget must have the given size or more (the given size is a minimum), while "maximum" means that the given size is an upper limit, so the behaviour you observe is consitent with semantics.
I would set the spinbox policy to "expanding" and the label to "preferred".
Related
I am testing a godot app, where there is a text heading along the top, and there are buttons along the bottom. For now I have a spacer in the middle to keep the heading at the top and the buttons at the bottom.
If I set Project Settings -> Display -> Stretch to disabled, then I can set a font and button size that looks reasonable for my laptop, and the font size for the heading and button doesnt shrink smaller and larger when the window is adjusted.
How do I guarantee and/or test that the size will be appropriate when the application is exported to iOS and Android? Is there some kind of guide that will help choose appropriate (non scaleable) button sizes for all devices?
How Controls are positioned
There are three intended ways to position a Control in Godot:
Placed in a Container. In this case the Container will control position and sizing of the child Control, taking into account "Size Flags".
See also Using Containers, and Containers.
By anchors (anchor_*) and margins (margin_*). They determine the position of the edges of the Control. The anchors are factors, and the margins are offsets.
For example, the leftmost part of the Control will be positioned at anchor_left * parent_width + margin_left, relative to the parent Control.
You will find presets in the "Layout" menu that appears in the tool bar when you have a Control selected.
See also Size and anchors.
By rect_position and rect_size. These are relative to the top left corner of the parent Control.
Ultimately the other ways to position the Control are changing these. And you can also change these even if you positioned the Control by other means… Which is not intended, but supported (because it is useful to add animations to the UI among other things).
Regardless of which one you use, Godot will respect rect_min_size. And yes, there is also rect_rotation and rect_scale which throw a wrench on the above explanation, but they works as you would expect.
And yes, it is not the easier to use system. Because of that, the designer is being improved for Godot 4 (currently on Alpha 3 at the time of writing).
To answer the question the title: If your stretch mode is set to disabled, and your UI is anchored to the top left (which is the default), you would resize the window and the UI would not scale or adapt to that change. I don't think you don't want the UI to adapt.
Making a top and bottom bars with containers
You can use a VBoxContainer, since we will have three bars stacked one on top of the other, vertically. And yes, the second one is a spacer.
First of all, you want the VBoxContainer to take the whole screen. So set it to the Layout preset "Full Rect". So, yes, we are placing the Container by anchors and margins.
And second, we want the spacer to take as much space as possible. To archive this we set "Expand" flag on size_flags_vertical of the spacer. This is what Size Flags are for.
And, of course, what you place inside the Container might or might not be more Containers.
Making a top and bottom bars with anchors and margins
Give the top bar the "Top Wide" preset. It will set the margins and anchors to have it stay at the top, take the full width, and take its minimum height.
And give the bottom bar the "Bottom Wide" preset. It will set the margins and anchors to have it stay at the bottom, take the full width, and take its minimum height.
You would need no spacer.
And, by the way, I remind you that anchors are margins are relative to the parent. So you can nest this approach. And yes, Controls that are not containers can also have children Controls
About stretch modes
As you know you have a choice between:
viewport: All the sizes will be computed with the original resolution, and then the resulting sizes are scaled to the resolution of the device.
2D: will also compute all the sizes with the original resolution, but instead of scaling the resulting sizes, it renders at that size and scales the image.
disabled: It will compute all the sizes with the actual resolution of the device. No scaling will happen.
Since both viewport and 2D, the size of the UI will not be computed with the actual resolution of the device. This makes the approaches I described to have the UI adapt less effective (less useful or less necessary, depending how you look at it). And thus, if we want to use those approaches effectively we will want the stretch mode set to disabled.
And, of course, there is also the aspect setting.
See also Multiple resolutions and Support multiple form factors and screen sizes.
Designing for small resolution
You can test on the editor how the UI adapts to the resolution, either by resizing the window, or by setting the Test Width and Test Height in Project Settings. You can, of course, also test on an actual smartphone. For instance, I often launch the game in my Android from the Godot editor when developing mobile games.
Circling back to the stretch modes, this is what happens with the text:
disabled: The text stays the same size. This means that the UI can become too small for the text.
viewport: the text scales. This means that the text can become too small to be legible.
2d: the text scales too… except since it is a image scaling it can become blurry, even harder to read.
If we only consider the text, there is no good option. Now, either design the UI for the specific target resolution… Or make one that can adapt. And for one that can adapt, I believe disabled is the best stretch mode as I was arguing above.
And of course you can script it
If you need to run some code when the resolution changes, you can connect to the "size_changed" signal of the root Viewport. And if you need to figure out if the device is in landscape or portrait mode you OS.screen_orientation, and if you really have to, you can create a custom Container.
Label in CN1 is limited to being a Single line.
Now that we have to use SpanLabel for anything that can take more than 1 line,
we face one issue.
When we have a strict design that uses consistent height for a list item, we have to give max/min lines allowed for the SpanLabel (At least that's how it works in Android And Flutter).
When I searched for anything that says line in SpanLabel file, I only found that word in one place, that too in a comment.
It did not feel right using fixed height/width property to a SpanLabel as they will vary with fonts and font sizes. The hight should be calculated with respect to the number of lines of the text & font config like font size, line spacing, padding, etc.
What is the right way to achieve consistent height across various SpanLabel despite the varied length of the text they display?
The "right way" would be the layout manager as it would allocate the right amount of space to the span label and everything else. E.g. if you use TableLayout you can allocate the height as percentage.
SpanLabel is technically a TextArea that's encapsulated. It has that distinction between rows/lines which isn't exposed within SpanLabel. But you can manipulate the underlying text area by using getTextComponent().
I use a Grid Layout inside my app. The grid layout I set to some fixed sizes.
myBootGridLayout->setContentsMargins(3,0,0,0);
myBootGridLayout->setRowMinimumHeight(0,25);
myBootGridLayout->setRowMinimumHeight(1,25);
myBootGridLayout->setRowMinimumHeight(2,25);
wdgBootFeatues->setFixedHeight(80);
For the QPushButton I use a size rule:
btnSelBootImagePath->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
But as you can see on the image, the ComboBox and Buttons have the same size but the LineEdit field is smaller. What I do wrong? Is there a trick to bring them on the common same size (Height) like in the QT documentation?
In case your question is to understand how to make sure that elements will have the same height, we should consider the following:
Layout might not necessarily ensure that some elements will have same height you would like, since it also relies on the size (horizontal and vertical) policy of the element in layout itself. In case you want to have QLineEdit and QPushButton instances to have the same height, you should set minimum height for each of them. Probably, it would even make sense to make the height fixed (i.e. set both minimum and maximum height to be the same values) for such elements to fit your needs, since both of these elements by default have fixed vertical size policy. This is for the reason, since most apps treat buttons and one line text fields in the same way.
In most cases, combining QVBoxLayout, QHBoxLayout and then QGridLayout is not necessary at all, since QGridLayout is much more flexible, and combines QVBoxLayout and QHBoxLayout features in a single layout under the hood at the first place, this it will probably satisfy all your needs (i.e. to represent you elements in a grid manner). Also, construction of UI elements will be slightly faster if less elements will be used.
Qt documentation might have such an effect because of the following reason - elements were tested on a different device. Qt does not try to make identical style sheets for widgets' elements across all platforms, thus visual differences will be everywhere. On some operating systems, button height is smaller than text field height by default, and this is completely normal.
One approach to make sure that size will get bigger than by default is to change size policy (vertical in your case). Code snippet changing size policy is correct basically. However, size policy is different thing than fixed height across elements. However, if your button and line edit would be in the same row, and both would have minimum expanding vertical policy, probably these elements would have the same height in that row.
Thus, probably to make sure the height of your elements remains the same is to set some minimum (and maximum as well in case vertical size policy is fixed) height through code or Qt Creator. This would be the easiest and least painful from thinking perspective approach. I am not sure if I have answered the question (it looks like that you answered yourself in your own way), but I am sure that I have introduced some thoughts that might come in handy when understanding Qt layouts.
How can I autoscale the text font size in a web page in order to make text in a div or p fit within given bounds?
There are nice solutions for Android, like this one, but I haven't found any for GWT.
Do you guys have any?
Thanks!
There are sevaral solutions to this problem:
(1) render the text, measure its width (myLabel.getOffsetWidth(), compare to the desired width, change font size if it does not fit and start over (remember to do this inside the Scheduler's deferred command, or your offset width will be zero);
(2) use FitText.js (http://fittextjs.com/);
(3) use canvas which can auto-fit text into provided space;
(4) use ellipsis when text overflows;
(5) use viewport units for text font (limited browser support at this time): http://css-tricks.com/viewport-sized-typography/
(6) create a different, more fluid UI design that handles content size better.
I'm having trouble using the layout manager system with Qt. This is going to be a Symbian app, so it should resize to different devices.
This is done by using the Layouts.
On the image below I used the Vertical Layout, but I don't understand how I can decide how much each cell should take in width and height.
I want the blue to be a top label background, but I don't want it to be as high as it is now.
Does anyone know how I can do this? (I'm new to Qt :))
You can set the maximum size for a widget by right clicking it and selecting 'Size Constraints'. Under that menu you can find actions that allow you to set the current displayed size as the maximum / minimum size for vertical / horizontal or both directions.
You can also set the numbers by hand by selecting the widget and by setting the number in the 'Property Editor'. They should be under the QWidget properties.
You cannot set the Height of a vertical layout directly, but you can set the height of the widget in which the vertical layout is.
If you want to split your Widgets so that the top widget takes 33.33% of the space, use the Stretch values. Set the top widget to 1 and the bottom widget to 2.