Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
layout.qdoc
Go to the documentation of this file.
1
// Copyright (C) 2016 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
/*!
4
\page layout.html
5
\title Layout Management
6
\ingroup qt-basic-concepts
7
\ingroup qt-gui-concepts
8
\brief A tour of the standard layout managers and an introduction to custom
9
layouts.
10
11
\previouspage Qt Widgets
12
\nextpage {Styles and Style Aware Widgets}{Styles}
13
14
\ingroup frameworks-technologies
15
16
The Qt layout system provides a simple and powerful way of automatically
17
arranging child widgets within a widget to ensure that they make good use
18
of the available space.
19
20
\section1 Introduction
21
22
Qt includes a set of layout management classes that are used to describe
23
how widgets are laid out in an application's user interface. These layouts
24
automatically position and resize widgets when the amount of space
25
available for them changes, ensuring that they are consistently arranged
26
and that the user interface as a whole remains usable.
27
28
All QWidget subclasses can use layouts to manage their children. The
29
QWidget::setLayout() function applies a layout to a widget. When a layout
30
is set on a widget in this way, it takes charge of the following tasks:
31
32
\list
33
\li Positioning of child widgets
34
\li Sensible default sizes for windows
35
\li Sensible minimum sizes for windows
36
\li Resize handling
37
\li Automatic updates when contents change:
38
\list
39
\li Font size, text or other contents of child widgets
40
\li Hiding or showing a child widget
41
\li Removal of child widgets
42
\endlist
43
\endlist
44
45
\section1 Qt's Layout Classes
46
47
Qt's layout classes were designed for hand-written C++ code, allowing
48
measurements to be specified in pixels for simplicity, so they are easy to
49
understand and use. The code generated for forms created using \QD also
50
uses the layout classes. \QD is useful to use when experimenting with the
51
design of a form since it avoids the compile, link and run cycle usually
52
involved in user interface development.
53
54
\annotatedlist geomanagement
55
56
\section1 Horizontal, Vertical, Grid, and Form Layouts
57
58
The easiest way to give your widgets a good layout is to use the built-in
59
layout managers: QHBoxLayout, QVBoxLayout, QGridLayout, and QFormLayout.
60
These classes inherit from QLayout, which in turn derives from QObject (not
61
QWidget). They take care of geometry management for a set of widgets. To
62
create more complex layouts, you can nest layout managers inside each other.
63
64
\list
65
\li A QHBoxLayout lays out widgets in a horizontal row, from left to
66
right (or right to left for right-to-left languages).
67
\image qhboxlayout-with-5-children.png
68
{Five buttons in horizontal layout}
69
70
\li A QVBoxLayout lays out widgets in a vertical column, from top to
71
bottom.
72
\image qvboxlayout-with-5-children.png
73
{Five buttons in vertical layout}
74
75
\li A QGridLayout lays out widgets in a two-dimensional grid. Widgets
76
can occupy multiple cells.
77
\image qgridlayout-with-5-children.png
78
{Five buttons in grid layout}
79
80
\li A QFormLayout lays out widgets in a 2-column descriptive label-
81
field style.
82
\image qformlayout-with-6-children.png
83
{Three buttons with text fields in form layout}
84
\endlist
85
86
87
\section2 Laying Out Widgets in Code
88
89
The following code creates a QHBoxLayout that manages the geometry of five
90
\l{QPushButton}{QPushButtons}, as shown on the first screenshot above:
91
92
\snippet layouts/layouts.cpp 0
93
\snippet layouts/layouts.cpp 1
94
\snippet layouts/layouts.cpp 2
95
\codeline
96
\snippet layouts/layouts.cpp 3
97
\snippet layouts/layouts.cpp 4
98
\snippet layouts/layouts.cpp 5
99
100
The code for QVBoxLayout is identical, except the line where the layout is
101
created. The code for QGridLayout is a bit different, because we need to
102
specify the row and column position of the child widget:
103
104
\snippet layouts/layouts.cpp 12
105
\snippet layouts/layouts.cpp 13
106
\snippet layouts/layouts.cpp 14
107
\codeline
108
\snippet layouts/layouts.cpp 15
109
\snippet layouts/layouts.cpp 16
110
\snippet layouts/layouts.cpp 17
111
112
The third QPushButton spans 2 columns. This is possible by specifying 2 as
113
the fifth argument to QGridLayout::addWidget().
114
115
QFormLayout will add two widgets on a row, commonly a QLabel and a QLineEdit
116
to create forms. Adding a QLabel and a QLineEdit on the same row will set
117
the QLineEdit as the QLabel's buddy. The following code will use the
118
QFormLayout to place three \l{QPushButton}{QPushButtons} and a corresponding
119
QLineEdit on a row.
120
121
\snippet layouts/layouts.cpp 18
122
\snippet layouts/layouts.cpp 19
123
\snippet layouts/layouts.cpp 20
124
\codeline
125
\snippet layouts/layouts.cpp 21
126
\snippet layouts/layouts.cpp 22
127
\snippet layouts/layouts.cpp 23
128
129
130
\section2 Tips for Using Layouts
131
132
When you use a layout, you do not need to pass a parent when constructing
133
the child widgets. The layout will automatically reparent the widgets
134
(using QWidget::setParent()) so that they are children of the widget on
135
which the layout is installed.
136
137
\note Widgets in a layout are children of the widget on which the layout
138
is installed, \e not of the layout itself. Widgets can only have other
139
widgets as parent, not layouts.
140
141
You can nest layouts using \c addLayout() on a layout; the inner layout
142
then becomes a child of the layout it is inserted into.
143
144
145
\section1 Adding Widgets to a Layout
146
147
When you add widgets to a layout, the layout process works as follows:
148
149
\list 1
150
\li All the widgets will initially be allocated an amount of space in
151
accordance with their QWidget::sizePolicy() and
152
QWidget::sizeHint().
153
154
\li If any of the widgets have stretch factors set, with a value
155
greater than zero, then they are allocated space in proportion to
156
their stretch factor (explained below).
157
158
\li If any of the widgets have stretch factors set to zero they will
159
only get more space if no other widgets want the space. Of these,
160
space is allocated to widgets with an
161
\l{QSizePolicy::Expanding}{Expanding} size policy first.
162
163
\li Any widgets that are allocated less space than their minimum size
164
(or minimum size hint if no minimum size is specified) are
165
allocated this minimum size they require. (Widgets don't have to
166
have a minimum size or minimum size hint in which case the stretch
167
factor is their determining factor.)
168
169
\li Any widgets that are allocated more space than their maximum size
170
are allocated the maximum size space they require. (Widgets do not
171
have to have a maximum size in which case the stretch factor is
172
their determining factor.)
173
\endlist
174
175
176
\section2 Stretch Factors
177
\target stretch factor
178
179
Widgets are normally created without any stretch factor set. When they are
180
laid out in a layout the widgets are given a share of space in accordance
181
with their QWidget::sizePolicy() or their minimum size hint whichever is
182
the greater. Stretch factors are used to change how much space widgets are
183
given in proportion to one another.
184
185
If we have three widgets laid out using a QHBoxLayout with no stretch
186
factors set we will get a layout like this:
187
188
\image layout1.png {Three evenly spaced widgets in a row}
189
190
If we apply stretch factors to each widget, they will be laid out in
191
proportion (but never less than their minimum size hint), e.g.
192
193
\image layout2.png {Three stretched widgets in a row}
194
195
196
\section1 Custom Widgets in Layouts
197
198
When you make your own widget class, you should also communicate its layout
199
properties. If the widget uses one of Qt's layouts, this is already taken
200
care of. If the widget does not have any child widgets, or uses a manual
201
layout, you can change the behavior of the widget using any or all of the
202
following mechanisms:
203
204
\list
205
\li Reimplement QWidget::sizeHint() to return the preferred size of the
206
widget.
207
\li Reimplement QWidget::minimumSizeHint() to return the smallest size
208
the widget can have.
209
\li Call QWidget::setSizePolicy() to specify the space requirements of
210
the widget.
211
\endlist
212
213
Call QWidget::updateGeometry() whenever the size hint, minimum size hint or
214
size policy changes. This will cause a layout recalculation. Multiple
215
consecutive calls to QWidget::updateGeometry() will only cause one layout
216
recalculation.
217
218
If the preferred height of your widget depends on its actual width (e.g.,
219
a label with automatic word-breaking), set the
220
\l{QSizePolicy::hasHeightForWidth()}{height-for-width} flag in the
221
widget's \l{QWidget::sizePolicy}{size policy} and reimplement
222
QWidget::heightForWidth().
223
224
Even if you implement QWidget::heightForWidth(), it is still a good idea to
225
provide a reasonable sizeHint().
226
227
For further guidance when implementing these functions, see the
228
\e{Qt Quarterly} article
229
\l{http://doc.qt.io/archives/qq/qq04-height-for-width.html}
230
{Trading Height for Width}.
231
232
233
\section1 Layout Issues
234
235
The use of rich text in a label widget can introduce some problems to the
236
layout of its parent widget. Problems occur due to the way rich text is
237
handled by Qt's layout managers when the label is word wrapped.
238
239
In certain cases the parent layout is put into QLayout::FreeResize mode,
240
meaning that it will not adapt the layout of its contents to fit inside
241
small sized windows, or even prevent the user from making the window too
242
small to be usable. This can be overcome by subclassing the problematic
243
widgets, and implementing suitable \l{QWidget::}{sizeHint()} and
244
\l{QWidget::}{minimumSizeHint()} functions.
245
246
In some cases, it is relevant when a layout is added to a widget. When
247
you set the widget of a QDockWidget or a QScrollArea (with
248
QDockWidget::setWidget() and QScrollArea::setWidget()), the layout must
249
already have been set on the widget. If not, the widget will not be
250
visible.
251
252
253
\section1 Manual Layout
254
255
If you are making a one-of-a-kind special layout, you can also make a
256
custom widget as described above. Reimplement QWidget::resizeEvent() to
257
calculate the required distribution of sizes and call
258
\l{QWidget::}{setGeometry()} on each child.
259
260
The widget will get an event of type QEvent::LayoutRequest when the
261
layout needs to be recalculated. Reimplement QWidget::event() to handle
262
QEvent::LayoutRequest events.
263
264
265
\section1 How to Write A Custom Layout Manager
266
267
An alternative to manual layout is to write your own layout manager by
268
subclassing QLayout. The
269
\l{layouts/flowlayout}{Flow Layout} example shows how to do this.
270
271
Here we present an example in detail. The \c CardLayout class is inspired
272
by the Java layout manager of the same name. It lays out the items (widgets
273
or nested layouts) on top of each other, each item offset by
274
QLayout::spacing().
275
276
To write your own layout class, you must define the following:
277
\list
278
\li A data structure to store the items handled by the layout. Each
279
item is a \l{QLayoutItem}{QLayoutItem}. We will use a
280
QList in this example.
281
\li \l{QLayout::}{addItem()}, how to add items to the layout.
282
\li \l{QLayout::}{setGeometry()}, how to perform the layout.
283
\li \l{QLayout::}{sizeHint()}, the preferred size of the layout.
284
\li \l{QLayout::}{itemAt()}, how to iterate over the layout.
285
\li \l{QLayout::}{takeAt()}, how to remove items from the layout.
286
\endlist
287
288
In most cases, you will also implement \l{QLayout::}{minimumSize()}.
289
290
291
\section2 The Header File (\c card.h)
292
293
\snippet code/doc_src_layout.cpp 0
294
295
296
\section2 The Implementation File (\c card.cpp)
297
298
\snippet code/doc_src_layout.cpp 1
299
300
First we define \c{count()} to fetch the number of items in the list.
301
302
\snippet code/doc_src_layout.cpp 2
303
304
Then we define two functions that iterate over the layout: \c{itemAt()}
305
and \c{takeAt()}. These functions are used internally by the layout system
306
to handle deletion of widgets. They are also available for application
307
programmers.
308
309
\c{itemAt()} returns the item at the given index. \c{takeAt()} removes the
310
item at the given index, and returns it. In this case we use the list index
311
as the layout index. In other cases where we have a more complex data
312
structure, we may have to spend more effort defining a linear order for the
313
items.
314
315
\snippet code/doc_src_layout.cpp 3
316
317
\c{addItem()} implements the default placement strategy for layout items.
318
This function must be implemented. It is used by QLayout::add(), by the
319
QLayout constructor that takes a layout as parent. If your layout has
320
advanced placement options that require parameters, you must provide extra
321
access functions such as the row and column spanning overloads of
322
QGridLayout::addItem(), QGridLayout::addWidget(), and
323
QGridLayout::addLayout().
324
325
\snippet code/doc_src_layout.cpp 4
326
327
The layout takes over responsibility of the items added. Since QLayoutItem
328
does not inherit QObject, we must delete the items manually. In the
329
destructor, we remove each item from the list using \c{takeAt()}, and
330
then delete it.
331
332
\snippet code/doc_src_layout.cpp 5
333
334
The \c{setGeometry()} function actually performs the layout. The rectangle
335
supplied as an argument does not include \c{margin()}. If relevant, use
336
\c{spacing()} as the distance between items.
337
338
\snippet code/doc_src_layout.cpp 6
339
340
\c{sizeHint()} and \c{minimumSize()} are normally very similar in
341
implementation. The sizes returned by both functions should include
342
\c{spacing()}, but not \c{margin()}.
343
344
\snippet code/doc_src_layout.cpp 7
345
346
347
\section2 Further Notes
348
349
\list
350
\li This custom layout does not handle height for width.
351
\li We ignore QLayoutItem::isEmpty(); this means that the layout will
352
treat hidden widgets as visible.
353
\li For complex layouts, speed can be greatly increased by caching
354
calculated values. In that case, implement
355
QLayoutItem::invalidate() to mark the cached data is dirty.
356
\li Calling QLayoutItem::sizeHint(), etc. may be expensive. So, you
357
should store the value in a local variable if you need it again
358
later within in the same function.
359
\li You should not call QLayoutItem::setGeometry() twice on the same
360
item in the same function. This call can be very expensive if the
361
item has several child widgets, because the layout manager must do
362
a complete layout every time. Instead, calculate the geometry and
363
then set it. (This does not only apply to layouts, you should do
364
the same if you implement your own resizeEvent(), for example.)
365
\endlist
366
367
\section1 Layout Examples
368
369
Many Qt Widgets \l{Qt Widgets Examples}{examples} already use layouts,
370
however, several examples exist to showcase various layouts.
371
372
\annotatedlist examples-layout
373
374
*/
qtbase
src
widgets
doc
src
widgets-and-layouts
layout.qdoc
Generated on
for Qt by
1.14.0