Usage of the QFormLayout

Published Monday July 7th, 2008 | by

Hi there. Introducing myself, my name is Friedemann Kleint, and I am one of the trolls hacking away at Qt Designer at the Berlin Office.

Today, I would like to draw your attention to the QFormLayout class. This is a special layout class suited to the common descriptive label – control arrangement found in many dialogs. It thas been developed in cooperation between Brisbane, Oslo and Berlin.

A typical form layout looks like this:

QFormLayout example 1

QFormLayout example 2

Note how the layout takes care of the label alignment according to the platform style. By the way, did you know that you can open several previews in different styles in Designer to compare them?

At first sight, QFormLayout looks like an ordinary grid. However, the layout also has policies for wrapping rows when it shrinks. For example, when setting the property rowWrapPolicy to WrapLongRows, we might get:

QFormLayout’s wrapping policy in effect

Let’s first have a look at the code. You might have created a such dialogs using QGridLayout, previously. This required some housekeeping of the current row. This is no longer necessary with QFormLayout using the addRow() convencience function. You don’t have to explicitly create the label, either:

QFormLayout *formLayout = new QFormLayout;
formLayout->addRow("Name", new QLineEdit);

For completeness, there is a setWidget() function which allows you to address single cells. It takes a row parameter and an ItemRole enumeration, which can be one of QFormLayout::LabelRole or QFormLayout::FieldRole.

In Qt Designer, you can create such arrangements as would in the case of a QGridLayout; you place the controls on a form and choose “Lay Out in a Form Layout”.

Hint: If you have existing .ui files containing such 2-column grid layouts and want to migrate them to the form layout, it might be sufficient to just replace the layout element by something like (after making a backup copy, of course ;-) ).

It is also possible to create arrangements with controls that span the 2 columns. This let’s you add controls with long labels (for example QComboBox) or QGroupBox elements. It can also be used to partition the form layout into sections by using spanning QLabel elements:

A form layout arrangement with spanning labels

In code, you would use the addRow() overload that takes just one QWidget* parameter.

In the upcoming 4.5 release, this functionality will also be available in Designer. Lonesone widgets on a QFormLayout get an active left/right resize handle that let’s you change the span:

Changing the span of a QFormLayout element in Designer

The per-cell API of the QFormLayout uses the SpanningRole enumeration value of ItemRole to handle these rows.

Summarizing, the QFormLayout should be used whereever the typical descriptive label – control arrangement occurs. The dialog will then look correctly on a all platforms.

Did you like this? Share it:

Posted in Qt

7 comments to Usage of the QFormLayout

Phil Thompson says:

I think a more flexible solution would have been to extend the functionality of QGridLayout, rather than introduce QFormLayout, by being able to specify pairs of adjacent columns that behave like QFormLayout’s columns do.

This would allow you to extend a row with other widgets (eg. a button that will show a dialog allowing the user to browse possible values of the field). It would also allow multi-field-column forms to be created.

David Johnson says:

How does one use a checkbox or radio button in a form layout? The trouble with these widgets is that their labels are to the right of the control. In most dialogs I’ve seen, they’ve been added to the “label row”. But in a form layout the labels might be right justified, resulting in a very awkward dialog. It would be nice if these widgets would work better with QFormLayout.

Daniel says:

I am developing both Qt and Java Swing desktop applications, and am quite disappointed with the Qt layout classes thus far. Sure, they are better than the standard (awful) Swing layout managers, but they are much more cumbersome and less powerful than free 3rd party Swing layout managers such as JGoodies FormLayout and MiG Layout.

I got excited for a moment when I learned about the new QFormLayout in Qt 4.4 (hoping it was a port of JGoodies FormLayout), but unfortunately QFormLayout turns out to be very simple and restrictive. It works great for these small “Hello World” layout examples, but is unsuited for even moderately complex forms.

Erik H. Bakke says:

Ideally, I’d just not add a label to the checkboxes but rather add an explicit label control for the purpose.

Although that may break with how checkboxes are typically laid out on the target platform, the user interface would fit more naturally with the rest of my user interface.

For radio buttons, perhaps you add them to a widget, lay them out in a vertical layout and then add your widget to the QFormLayout?
That will give you a label for your radio buttons group as well as individual labels per radio button.

Friedemann Kleint says:

I have brought task 205222 to the attention of the
layout trolls again; it should be dealt with in the near future.

The QFormLayout has its origin in embedded development, so it is primarily
intended for simple up to moderately complicated arrangements. However, it
is also possible to nest layouts by for example adding rows with spanning
layouts.

> This would allow you to extend a row with other widgets (eg. a button that
> will show a dialog allowing the user to browse possible values of the
> field).

You can do this currently by adding a layout to the row, e.g. something like
this:

QHBoxLayout *hb = new HBoxLayout;
hb->addWidget(new LineEdit);
hb->addWidget(new QPushButton);
formlayout->addRow(“File”, hb);

> How does one use a checkbox or radio button in a form layout? The trouble
> with these widgets is that their labels are to the right of the control. In
> most dialogs I’ve seen, they’ve been added to the “label row”. But in a
> form layout the labels might be right >justified, resulting in a very
> awkward dialog. It would be nice if these widgets would work better with
> QFormLayout.

The tough part is there isn’t one standard way of handling them (at least
from the examples I’ve seen). One typically wants it spanning on Windows and
in the field column on Mac. We can look more at platform guidelines — if
each platform has a standard way maybe we can support them better.

> I got excited for a moment when I learned about the new QFormLayout in Qt
> 4.4 (hoping it was a port of JGoodies FormLayout), but unfortunately
> QFormLayout turns out to be very simple and restrictive. It works great for
> these small “Hello World” layout >examples, but is unsuited for even
> moderately complex forms.

Feel free to provide examples of forms that QFormLayout doesn’t handle well, and
we’ll see what we can do to improve it. Note that you can always fall back to
a grid layout for really complex behaviour.

Thanks for the feedback!

Daniel says:

>> I got excited for a moment when I learned about the new QFormLayout in Qt
>> 4.4 (hoping it was a port of JGoodies FormLayout), but unfortunately
>> QFormLayout turns out to be very simple and restrictive. It works great for
>> these small “Hello World” layout >examples, but is unsuited for even
>> moderately complex forms.

> Feel free to provide examples of forms that QFormLayout doesn’t handle well, and
> we’ll see what we can do to improve it. Note that you can always fall back to
> a grid layout for really complex behaviour.

> Thanks for the feedback!

Thanks Friedemann, I will try to put together a complete enhancement request and send it to Qt support when I have some free time. By the way, I *am* currently using QGridLayout for pretty much everything, and my complaint is that it is not as powerful as Java layout managers such as Form Layout and MiG Layout.

Commenting closed.