Sunday 21 April 2013

Qt Layout Tutorial - Part II

Note: Now that the tutorial is finished, here are links to part I, part III, and the files.

Before we proceed with our tutorial, a few notes about maximumSize:
  • Qt Designer won't let you resize a widget beyond its maximumSize. So, when you want to experiment with it, make sure its value is someHugeValueDefinitelyLargerThan42 (don't ask, just read part I), so you can resize it to your heart's content.
  • If you want your widget to expand with the layout, you'll have to take that into account when you change maximumSize. In this example, since I don't want area B to expand, I'm setting maximumSize equal to the current size.
  • Even though I said you don't need to change anything on push buttons, setting their maximumSize is always an option if you're having trouble getting them to keep your desired size.
Also, if you're having trouble with widget sizes in different layouts, the first thing to do is resize the layouts so they have similar dimensions. This is especially helpful with the push buttons in this tutorial, if you don't want to change any of their properties.

One final note: For some reason I didn't figure out (but I admit I didn't do much research on it), the vertical spacer I placed on step 3 of part I went missing when I reopened the project for this post. I added it back, closed and re-opened Qt Creator, opened the project and... gone again. I know once we apply a layout (which we'll do in part III) it stays put, so I've just accepted it as another little quirk I'll have to live with.

Now, let's continue our Qt layout tutorial.

In part I we've divided the form in 3 areas, and filled area B1 (you may want to refer to part I, since I've defined these names there). Now, let's take care of area B2.

Area B2 will contain 6 rows of widgets (don't add them yet, just keep reading):
  • label + line edit + label + line edit + label + line edit + horizontal spacer + push button.
  • label + line edit + horizontal spacer + push button.
  • label + line edit + label + line edit + label + line edit + horizontal spacer + push button.
  • label + line edit + horizontal spacer + label + line edit + horizontal spacer.
  • label + combo box.
  • push button.
These widgets will need the same changes as we applied to the widgets we added to B1, otherwise B2 would cause area B to expand. So, instead of adding the widgets and changing all the properties again, I'll copy/paste as much as I can. Naturally, you're encouraged to change the widgets text and size, and play around with it; if a widget doesn't behave as expected when you apply a layout, take a look at its maximumSize and sizePolicy.

Also, don't worry if the layouts aren't perfectly aligned or have small differences in size. When we apply the final layouts in part III, everything will fall into place.

1. B2 - Row 1
1.1. Select a label and a line edit in B1, and copy/paste. Then, drag the copies to B2. Adjust the text and size of both widgets according to what you want. Repeat until you have 3 labels and 3 line edits in B2. Notice that you won't have to change sizePolicy, because the original widgets already had the correct value for our goal.

1.2. Select the horizontal spacer in B1, copy/paste, and drag it to B2. Once again, you won't have to change anything else.

1.3. You can add a new push button, instead of using copy/paste, since we didn't change anything on the push buttons.

2. B2 - Rows 2-6
For row 2, select a label, a line edit, a horizontal spacer and a push button from row 1. Copy/paste, and drag. Row 3 happens to have the exact same widgets as row 1, so you can just copy/paste row 1. For row 4, you can copy/paste a label + edit + spacer twice. And for rows 5 & 6, just add the widgets, setting the combo box's sizePolicy.HorizontalPolicy to "Minimum".

3. Next, we apply a horizontal layout to row 1. Everything should become neatly spaced, within the layout. Then, we apply a horizontal layout to row 2.

Now, since row 2 also has a push button at the right end, I'd like those buttons aligned. In order to achieve that, I aligned both layouts at the left border and fiddled with the sizeHint.Width on row 2's spacer. This is the best process I've discovered to align widgets on a layout - change their size in the property sheet. I did the same with the edit widget on row 2 to align it on the right with the 2nd edit widget on row 1.

4. Row 3 should be easy, since it's identical to row 1, so we just apply a horizontal layout. Row 4, however, may require some tweaking to get a widget alignment that looks good with the other rows. Some options are - change the dimension of the edits in rows 1-3 to align them with the second edit on row 4, or remove the second spacer in row 4 and let the 2nd edit align to the right.

I went with the first option. And that was good, because it showed me again that, while I can get around designing this UI, that doesn't mean I know exactly what's going on. I increased the size on the 3 edits in row 1. Instead of "compressing" the spacer, this sent the push button off the edge of group box. I resized the layout to fit within the group box, and, again, the spacer remained constant and the push button shrank. I only got the spacer to shrink and the push button to return to its "normal" (read "desired") size by manually reducing the spacer's sizeHint.Width on the property inspector.

However, when I did the same thing in row 2, everything went smoothly. Even though the push button was also pushed off, when I resized the layout, it went back into place and the spacer shrank automatically. I even increased the spacer's sizeHint.Width, which pushed the button off again, but when I resized the layout, back into place it went, with no need for manual resizing.

I checked the properties on all the widgets in rows 1 and 2, matching each identical widget - label to label, edit to edit, etc. All size policies were identical, all the mix/max sizes were set in the same fashion. So, why the different behaviour? No idea. At least row 3 behaved like row 1, so whatever's happening, it's consistent.

Then, I set the first spacer on row 4 with sizeType "Maximum" and adjusted the maximumSize.Width on the second edit, until it aligned on the right with the first edit on row 3.

5. Row 5 is easy, we just select both widgets and apply a horizontal layout. Then, we resize the layout, and the combo box will expand. Row 6 is just the push button, so we'll leave it be, there's no need to apply any layout.

That's it for now, we'll wrap it up next time.

No comments:

Post a Comment