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