I'm trying to make components resize to keep their starting ratio depending on the size of the window.
Using an AnchorPane I can set the constraints to be in pixels, the problem is that resizing the window to make it bigger makes all the elements stretch to keep the exact same amount of pixels defined in the constraints.
What I want to be able to do is define them in terms of percentages or in some other way in order to keep the aspect ratio and position consistent between window sizes.
So far I've seen two possible solutions:
Compute constraints on the fly
Compute the constraints on each resize event as proposed in this question:
AnchorPane Constraints in percentages, but that means that piece of code could be potentially called once every pixel change.
Nest Panes and surround the element with rows/columns
Another way is to nest panes and components, something like:
Root > AnchorPane > GridPane > AnchorPane > Component
Now to position it where you want you add one row above, one below, one column before and one after where your component should be (surrounding it) and set the resize percentage of them.
This works by "leaking" the resizing behavior of the AnchorPane to the Component, and the width/height weight of the rows/columns.
My question is: Is there a better way to do this?
While both could work, none of them seem quite right. One involves calling code once every pixel change and the other one adds (a lot of) unused elements.
Example using the second approach
Related
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.
I want to make something like a gridlayout but the layout must decide how many elements can be fitted in a row, and when the row is full continue with the next row.
QtGridLayout also fixes the columns width.
I want to something like this (this pictures was manually organised in Horizontals and verticals grids)
When the image size changes one of the buttons goes to first row.
((In this compositions both images looks with the same size, but actually second one is wider than first one).
Some one answer this question but remove it, so the credits are for my unknown friend.
Qt have an example named Flow Layout Example for a widget based form and another for Graphics View widget.
I am looking for a way to draw a node on top of the neighbouring ones in a HBox. Default behaviour means it is drawn on top of the previous one, but that also means the next one is drawn on top of it. For other containers, one could use the Node.toFront(), but changing the position of the node in the list containing a HBox's children also changes the actual position in the HBox, which is unwanted behaviour in my case. I appreciate any help, thank you.
EDIT:
The overlapping occurs when applying a DropShadow effect on an Ellipse and wrapping them in a StackPane along with a Text. It looks like the effect has a weird interaction with the HBox, as it works as intended without it. After adding the effect, it allocates more horizontal space for the ellipse, but not enough to cover the margins of the effect. Also, when clicking anywhere in the whole right half of the black rectangle, the mouse click is dispatched to the stackPane event handler, not to the rectangle's.
This happens
In VBox and HBox, the Node.toFront() and Node.toBack() functions will change the layout, so they are not usable. If you are using JavaFX 9+,you can use the viewOrder commands to change the rendering order of the Node in its Parent:
Node.getViewOrder()
Node.setViewOrder()
The default value of viewOrder is 0, so setting it to -1 will render it above all others. You can customize this to get specific orders. It also has a CSS property -fx-view-order.
I am using ItemTemplate ( that is ViewCell ). I got know about the Orientation article in Xamarin documentation but there is no point about handling ListView orientation.
Hope to get the answer
Screen shots
http://i.stack.imgur.com/lkMvC.png
http://i.stack.imgur.com/5PrJj.png
As you can see from your screenshots, this is not an orientation problem, your listview IS the full width in both cases, what is quite possibly wrong are your layout options.
Can you show us your item template definition?
You are using a grid inside the ViewCell?
In that case, first make sure the grid's horizontal options are set to FillAndExpand, then check the grid column size definition.
Can you also show us the grid's column size definitions?
If they all have fixed sizes assigned, then they will always be that size, no matter how much unsued space there is.
There are 2 ways to make them use more space.
If possible, you should use the "star" sizes. This is where you give your columns sizes as portions of the available space.
If you give your first column the size 1*
and the second column size 1*
they will both take exactly half of the available width.
You can use any other numbers to select portions, such as three columns with sizes 5* 3* 1*
Which would make your first column 5 times as big as the third, and the second column would be 3 times as big as the third.
Again, in total, they will take the entire available width.
The second column sizing option is to use "Auto" sized columns, which will size the columns according to the elements inside them. Whatever size the largest element inside that column (in any of the rows) takes, that is the size that column will have.
To take the whole screen width in this case, at least one of the columns content should have "AndExpand" on it's horizontal options.
This is somewhat easier as it will automatically size the columns and you just take care of populating them properly with content, but be wary as this approach is significantly slower.
Finally, if you experience performance issues, consider implementing the ViewCell with an AbsoluteLayout. It can be a bit more pain to set up, but should work faster than grid if you have a bunch of rows inside the list view and a bunch of data in each row.
Basically I've got a QGridLayout with a few widgets in it. The important ones are 2 labels, which I use for drawing images to the screen. Well, if the user wants, he can change the resolution of the incoming images, thus, forcing the Labels to resize.
Let's assume the initial size of the label is 320x240. The user changes the VideoMode to 640x480, the label and the entire GUI resizes perfectly. But when the user switches back to 320x240, the label shrinks, but the Layout/Window does NOT.
I've played around with sizePolicies and sizeHints, and resize(0,0), but nothing did the trick. Could somebody help me with this?
Here some screenshots to clarify the problem:
You need to set the size constraint of the layout holding all your widgets to "SetFixedSize". Although the name doesn't sound like it will work, it ensures that your layout will only use the space it needs. You will not have the problem like you do in your second screenshot.
Example:
mainLayout.setSizeConstraint(QLayout::SetFixedSize);
QLayout::setSizeConstraint(QLayout::SetFixedSize) solves this problem well when you prefer keeping your widget's size fixed at all times--that is, if you'd like it to always be fixed to its "packed" size (which may still vary as the child widgets change size). That is what the "fixed" means there: "fixed" to the correct size, even as the latter varies. (In Qt terms, what I'm calling the "packed" size is simply the widget's sizeHint.)
But a constraint may be too strong a solution in some instances. In particular, if you apply it to a top-level window, then the user will not be free to resize the window. If you don't like that, you can instead perform the "set size to sizeHint" operation instantaneously each time it's needed, rather than imposing it as an unrelenting constraint. The way to do that is to call QWidget::adjustSize().
http://doc.qt.io/qt-5/qwidget.html#adjustSize
Note that if the container whose children are changing size is not the top-level window, then adjustSize() may have to be called recursively on the container and its parents. (In my case I had to do that, anyway. I also tried the size-constraint scheme, and found that applying the constraint at only the topmost level was successful in compacting all levels. I haven't enough knowledge of Qt to comment usefully on these observations, so I merely share them.)
You need to store the original size of your widget parent window before applying any changes to the layout and restore it when the user switches back to the original.
Notice that you need to work with the widget parent window size and not the widget parent size.
in your widget before applying the layout changes:
minimumWindowSize = this->window().size();
when you finished reorganizing the widget to the compact size
this->window().resize(minimumWindowSize);
So that is exactly what i'm doing in mu project.
Resolution os doesn't matter. I have only to have a widget for rendering video, or image in your case.
void MainWindow::resizeEvent(QResizeEvent* event)
{
QMainWindow::resizeEvent(event);
if ((player != 0) && ((player->isPlaying()) || player->isLoaded() || player>isLoaded())){
renderer->resize(ui->mainVideoWidget->width(),ui->mainVideoWidget->height());
resizeFilter();
}
}