PDA

View Full Version : Unexpected QGridLayout behaviour



Binary91
15th November 2016, 15:37
Hello,

I'm trying to position some elements in a QGridLayout, but I always get unexpected alignments.

Take a look at the screenshot:
12210
The marked area (red line) between the first two edit blocks is larger than the area between block 2 and 3.
Also, there is some unexpected space on the right side of block 3 (blue line).

I guess, that moving block three to the right edge of its column (blue line) would solve the problem.

That is how the code looks like:

this->layoutMain = new QVBoxLayout;12210
this->layoutTop = new QGridLayout;
this->lAerodromeDeparture = new QLabel(this->sAerodromeDeparture);
this->layoutTop->addWidget(this->lAerodromeDeparture, 0, 0, 1, 3);
this->editAerodromeDeparture = new myQLineEdit;
this->editAerodromeDeparture->setMinimumWidth(150);
this->layoutTop->addWidget(this->editAerodromeDeparture, 1, 0, 1, 3);
this->lCodeDeparture = new QLabel(this->sCodeDeparture);
this->layoutTop->addWidget(this->lCodeDeparture, 0, 3, 1, 1);
this->cbCodeDeparture = new QComboBox;
this->cbCodeDeparture->setMinimumWidth(100);
this->cbCodeDeparture->insertItems(0, this->slAerodromeCodes);
this->layoutTop->addWidget(this->cbCodeDeparture, 1, 3, 1, 1);

this->lCoordsDeparture = new QLabel(this->sCoordsDeparture);
this->layoutTop->addWidget(this->lCoordsDeparture, 2, 0, 1, 3);
this->editCoordsDepartureV1 = new myQLineEdit;
this->editCoordsDepartureV1->setFixedWidth(25);
this->layoutTop->addWidget(this->editCoordsDepartureV1, 3, 0, 1, 1);
this->editCoordsDepartureV2 = new myQLineEdit;
this->editCoordsDepartureV2->setFixedWidth(25);
this->layoutTop->addWidget(this->editCoordsDepartureV2, 3, 1, 1, 1);
this->editCoordsDepartureV3 = new myQLineEdit;
this->editCoordsDepartureV3->setFixedWidth(25);
this->layoutTop->addWidget(this->editCoordsDepartureV3, 3, 2, 1, 1);
this->editCoordsDepartureH1 = new myQLineEdit;
this->editCoordsDepartureH1->setFixedWidth(25);
this->layoutTop->addWidget(this->editCoordsDepartureH1, 4, 0, 1, 1);
this->editCoordsDepartureH2 = new myQLineEdit;
this->editCoordsDepartureH2->setFixedWidth(25);
this->layoutTop->addWidget(this->editCoordsDepartureH2, 4, 1, 1, 1);
this->editCoordsDepartureH3 = new myQLineEdit;
this->editCoordsDepartureH3->setFixedWidth(25);
this->layoutTop->addWidget(this->editCoordsDepartureH3, 4, 2, 1, 1);

this->layoutMain->addLayout(this->layoutTop);
this->setLayout(this->layoutMain);Can anyone imagine what causes that unexpected behaviour?

Thank you in anticipation!

Kind regards,
Binary

d_stranz
15th November 2016, 21:41
Why aren't you using Qt Designer to lay this out? So much easier than editing, compiling, and running code just to see the effect of a UI change.

You can force equal spacing on your three line edit widgets by putting them into a QHBoxLayout and then adding *that* to the grid layout. Or add horizontal QSpacerItem between the first and second and second and third line edits.

By the way, I found out that setting a fixed width on QLineEdit and other text widgets is dangerous. When I went from a 2K to a 4K monitor, I had to change the font magnification from 100% to 125% because the fonts were too small. The first time I ran my Qt application, I found that none of the strings would fit in my fixed-width text widgets. So unless you are designing for an application that will run on a display with known resolution, be careful about fixed sizes for anything.

anda_skoa
15th November 2016, 21:44
Not sure what you consider unexpected since you are setting fixed sized and thus not allowing the widgets to fill their respective cells.

Cheers,
_

Binary91
16th November 2016, 11:51
@anda_skoa:
Well, I did expect that in a row with 3 edits it should not matter whether they have a fixed size or not. In both situations, they should have the same distance to each other. But as you can see in the screenshot, they do not.
I can't imagine why QGridBox inserts a larger space between edit1 and edit2 than edit2 and edit3 in a row.

Each edit should be positioned at the top left of a "cell" in the grid layout. Fixing its with should then only result in free space on the right side of the edits, but the distance between them should be the same, because they all have the same fixed width. That is how I understand grid layout positioning. Maybe I'm wrong...


@d_stranz:
Thank you for that hint. Well, how does other software handle with this problem? I mean, I've never seen a programm with a GUI where all widgets grow with the window by changing its size manually. Instead, edits, buttons etc. seem to appear fixed... Is there a way to set a fixed size calculated to the screen width/height/resolution or how does "professional" software handle with that?

Kind regards,
Binary

Binary91
16th November 2016, 14:16
And there is one more thing with QGridLayout that doesn't seem to be correct behaviour for me:

To fix the distance problem mentioned in the previous post, I tried to set the horizontal & vertical spacing to zero with:

layoutGrid->setSpacing(0);
// alternatively
layoutGrid->setHorizontalSpacing(0);
layoutGrid->setVerticalSpacing(0);The result was a correct vertical spacing of zero, so the bottom of edit in row1 touches the top edge of the edit in row2 with no space between.
Problem: horizontal spacing didn't change or there is still some space like 5px.

Problem2: While resizing the window, horizontal space grows. So I tried to set ColumnStretch of all columns to zero:

for(int i = 0; i < 5; i++)
this->layoutGrid->setColumnStretch(i,0);Result: nothing changed.
Documentation says that if all columns have a stretch-factor of zero, then it can be ignored.
Solution: I tried to set stretch factor of the first column to 1:

this->layoutGrid->setColumnStretch(0,1);
for(int i = 1; i < 5; i++)
this->layoutGrid->setColumnStretch(i,0);Result: still nothing changed!! All columns stretch while resizing the window. But no row stretches.
Then I thought that the solution could be adding a second layout right to the grid layout and give it a stretch factor, because I think that the correct row behaviour (no stretch) is a result of the layouts above the grid (they stretch while vertically resizing the window).
Result: the second layout doesn't stretch!! I don't know why! The first layout shouldn't stretch and it does, and the second layout right next to it should stretch and it doesn't!

Well, I think I eighter missed some important things about GridLayouts or otherwise this Qt class is not good to handle. All of my commands are ignored and the layout does what it wants to do...

anda_skoa
16th November 2016, 17:01
Well, I did expect that in a row with 3 edits it should not matter whether they have a fixed size or not.

Possibly, but fixed sizes can easily mess up layouts if not paired with some dynamically sizable element.
Gets the layout manager into conflicts.



Each edit should be positioned at the top left of a "cell" in the grid layout. Fixing its with should then only result in free space on the right side of the edits, but the distance between them should be the same, because they all have the same fixed width. That is how I understand grid layout positioning. Maybe I'm wrong...

Your layout has no defining elements, as the lineedit are too short for the text that spans multiple columns.
So the columns are resized to match the need of the text, it could very well be that the last column is the one providing the overflow width.



I mean, I've never seen a programm with a GUI where all widgets grow with the window by changing its size manually. Instead, edits, buttons etc. seem to appear fixed... Is there a way to set a fixed size calculated to the screen width/height/resolution or how does "professional" software handle with that?


Actually most GUIs do that as it is the only sane way to deal with different size requirements, e.g. different font or font size, different language, different widget style.

Cheers,
_

Binary91
16th November 2016, 17:23
Thank you for your post.

So, summarized, it is a good idea to define dynamic elements in the grid layout.
Well, that is what I tried to do. I passed some columns a stretch factor and I passed QSpacerItems. Both ways did not prevent the layout from stretching my edits.

Could you post a short example of a grid layout with only 6 edits (3x2) with a fixed space between them and one extra column that does the dynamic part?
I think this is not the most complex thing so I do not understand why it seems to be impossible to realize it.

I mean, when I add a second grid layout with 6 elements (labels) within, it doesn't change any space while resizing the window. Only my left grid layout resizes like it wants to, no matter how I try to prevent it with fix stretch factors, adding spaceritems etc.

I only get these problems with grid layouts. That's why I always use hbox- and vbox layouts. But for this purpose (12x5 edits with labels between) a grid layout seems to be better. But if I can't define space, margin and stretch within it like I need it, I will scrap that and use hbox/vbox layouts...

Take a look at the screenshot:
12215
This is coded with a script language, not with Qt.
I try to code this with Qt now.

How would you realize this? Two grid layouts in a hbox layout like I try to do?
Then pls tell me how I can realize fix distances (I don't mean fix element sizes as we talked about better not to do that) with horizontal & vertical center alignment in a row/column by adding dynamic columns/rows with no content that stretch while resizing the window..

anda_skoa
17th November 2016, 11:19
Not sure if I understand your requirements correctly, what about this?
12219

Cheers,
_

d_stranz
17th November 2016, 18:09
what about this?

Probably should add a vertical spacer at the bottom to keep everything compact when the window is vertically resized. Otherwise, that's the way I would do it.

Binary91
21st November 2016, 19:57
Hey guys and sorry for the belated reply.

Your example looks good. Thank you for that!
Also, I did find out how to use SpacerItems as stretch items. I always forgot to change the QSizePolicy, so nothing could stretch. Now, after removing fixed sizes and giving each column diffent stretch factors, I can handle correct grid positioning with expanding spacers.

Maybe one last question:
After having removed all fix widths/heights, each edit in my gui has a predefined maximal and a predefined minimal width. But, not every edit is displayed with the same width when I run the program.
Instead, some edits are shown with a smaller width and when I enlarge the window, they grow to the maximum width like the other edits have it from the beginning.

Is there a way to set fixed "starting widths" for every edit?

Kind regards,
Binary