doc/src/widgets-and-layouts/layout.qdoc
changeset 0 1918ee327afb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/src/widgets-and-layouts/layout.qdoc	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,396 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+    \group geomanagement
+    \title Layout Classes
+*/
+
+/*!
+    \page layout.html
+    \title Layout Management
+    \brief A tour of the standard layout managers and an introduction to custom
+    layouts.
+    
+    \previouspage Widget Classes
+    \contentspage Widgets and Layouts
+    \nextpage {Implementing Styles and Style Aware Widgets}{Styles}
+
+    \ingroup frameworks-technologies
+
+    The Qt layout system provides a simple and powerful way of automatically
+    arranging child widgets within a widget to ensure that they make good use
+    of the available space.
+
+    \tableofcontents
+
+    \section1 Introduction
+
+    Qt includes a set of layout management classes that are used to describe
+    how widgets are laid out in an application's user interface. These layouts
+    automatically position and resize widgets when the amount of space
+    available for them changes, ensuring that they are consistently arranged
+    and that the user interface as a whole remains usable.
+
+    All QWidget subclasses can use layouts to manage their children. The
+    QWidget::setLayout() function applies a layout to a widget. When a layout
+    is set on a widget in this way, it takes charge of the following tasks:
+
+    \list
+    \o Positioning of child widgets.
+    \o Sensible default sizes for windows.
+    \o Sensible minimum sizes for windows.
+    \o Resize handling.
+    \o Automatic updates when contents change:
+        \list
+        \o Font size, text or other contents of child widgets.
+        \o Hiding or showing a child widget.
+        \o Removal of child widgets.
+        \endlist
+    \endlist
+
+    \section1 Qt's Layout Classes
+    
+    Qt's layout classes were designed for hand-written C++ code, allowing
+    measurements to be specified in pixels for simplicity, so they are easy to
+    understand and use. The code generated for forms created using \QD also
+    uses the layout classes. \QD is useful to use when experimenting with the
+    design of a form since it avoids the compile, link and run cycle usually
+    involved in user interface development.
+
+    \annotatedlist geomanagement
+
+    \section1 Horizontal, Vertical, Grid, and Form Layouts
+
+    The easiest way to give your widgets a good layout is to use the built-in
+    layout managers: QHBoxLayout, QVBoxLayout, QGridLayout, and QFormLayout.
+    These classes inherit from QLayout, which in turn derives from QObject (not
+    QWidget). They take care of geometry  management for a set of widgets. To
+    create more complex layouts, you can nest layout managers inside each other.
+
+    \list
+        \o  A QHBoxLayout lays out widgets in a horizontal row, from left to
+            right (or right to left for right-to-left languages).
+            \image qhboxlayout-with-5-children.png
+
+        \o  A QVBoxLayout lays out widgets in a vertical column, from top to
+            bottom.
+            \image qvboxlayout-with-5-children.png
+
+        \o  A QGridLayout lays out widgets in a two-dimensional grid. Widgets
+            can occupy multiple cells.
+            \image qgridlayout-with-5-children.png
+
+        \o  A QFormLayout lays out widgets in a 2-column descriptive label-
+            field style.
+            \image qformlayout-with-6-children.png
+    \endlist
+
+
+    \section2 Laying Out Widgets in Code
+
+    The following code creates a QHBoxLayout that manages the geometry of five
+    \l{QPushButton}s, as shown on the first screenshot above:
+
+    \snippet doc/src/snippets/layouts/layouts.cpp 0
+    \snippet doc/src/snippets/layouts/layouts.cpp 1
+    \snippet doc/src/snippets/layouts/layouts.cpp 2
+    \codeline
+    \snippet doc/src/snippets/layouts/layouts.cpp 3
+    \snippet doc/src/snippets/layouts/layouts.cpp 4
+    \snippet doc/src/snippets/layouts/layouts.cpp 5
+
+    The code for QVBoxLayout is identical, except the line where the layout is
+    created. The code for QGridLayout is a bit different, because we need to
+    specify the row and column position of the child widget:
+
+    \snippet doc/src/snippets/layouts/layouts.cpp 12
+    \snippet doc/src/snippets/layouts/layouts.cpp 13
+    \snippet doc/src/snippets/layouts/layouts.cpp 14
+    \codeline
+    \snippet doc/src/snippets/layouts/layouts.cpp 15
+    \snippet doc/src/snippets/layouts/layouts.cpp 16
+    \snippet doc/src/snippets/layouts/layouts.cpp 17
+
+    The third QPushButton spans 2 columns. This is possible by specifying 2 as
+    the fifth argument to QGridLayout::addWidget().
+
+    Finally, the code for QFormLayout is ..
+
+
+    \section2 Tips for Using Layouts
+
+    When you use a layout, you do not need to pass a parent when constructing
+    the child widgets. The layout will automatically reparent the widgets
+    (using QWidget::setParent()) so that they are children of the widget on
+    which the layout is installed.
+
+    \note Widgets in a layout are children of the widget on which the layout
+    is installed, \e not of the layout itself. Widgets can only have other
+    widgets as parent, not layouts.
+
+    You can nest layouts using \c addLayout() on a layout; the inner layout
+    then becomes a child of the layout it is inserted into.
+
+
+    \section1 Adding Widgets to a Layout
+
+    When you add widgets to a layout, the layout process works as follows:
+
+    \list 1
+        \o  All the widgets will initially be allocated an amount of space in
+            accordance with their QWidget::sizePolicy() and
+            QWidget::sizeHint().
+
+        \o  If any of the widgets have stretch factors set, with a value
+            greater than zero, then they are allocated space in proportion to
+            their stretch factor (explained below).
+
+        \o  If any of the widgets have stretch factors set to zero they will
+            only get more space if no other widgets want the space. Of these,
+            space is allocated to widgets with an
+            \l{QSizePolicy::Expanding}{Expanding} size policy first.
+
+        \o  Any widgets that are allocated less space than their minimum size
+            (or minimum size hint if no minimum size is specified) are
+            allocated this minimum size they require. (Widgets don't have to
+            have a minimum size or minimum size hint in which case the strech
+            factor is their determining factor.)
+
+        \o  Any widgets that are allocated more space than their maximum size
+            are allocated the maximum size space they require. (Widgets do not
+            have to have a maximum size in which case the strech factor is
+            their determining factor.)
+    \endlist
+
+
+    \section2 Stretch Factors
+    \keyword stretch factor
+
+    Widgets are normally created without any stretch factor set. When they are
+    laid out in a layout the widgets are given a share of space in accordance
+    with their QWidget::sizePolicy() or their minimum size hint whichever is
+    the greater. Stretch factors are used to change how much space widgets are
+    given in proportion to one another.
+
+    If we have three widgets laid out using a QHBoxLayout with no stretch
+    factors set we will get a layout like this:
+
+    \img layout1.png Three widgets in a row
+
+    If we apply stretch factors to each widget, they will be laid out in
+    proportion (but never less than their minimum size hint), e.g.
+
+    \img layout2.png Three widgets with different stretch factors in a row
+
+
+    \section1 Custom Widgets in Layouts
+
+    When you make your own widget class, you should also communicate its layout
+    properties. If the widget has a one of Qt's layouts, this is already taken
+    care of. If the widget does not have any child widgets, or uses manual
+    layout, you can change the behavior of the widget using any or all of the
+    following mechanisms:
+
+    \list
+        \o  Reimplement QWidget::sizeHint() to return the preferred size of the
+            widget.
+        \o  Reimplement QWidget::minimumSizeHint() to return the smallest size
+            the widget can have.
+        \o  Call QWidget::setSizePolicy() to specify the space requirements of
+            the widget.
+    \endlist
+
+    Call QWidget::updateGeometry() whenever the size hint, minimum size hint or
+    size policy changes. This will cause a layout recalculation. Multiple
+    consecutive calls to QWidget::updateGeometry() will only cause one layout
+    recalculation.
+
+    If the preferred height of your widget depends on its actual width (e.g.,
+    a label with automatic word-breaking), set the
+    \l{QSizePolicy::hasHeightForWidth()}{height-for-width} flag in the
+    widget's \l{QWidget::sizePolicy}{size policy} and reimplement
+    QWidget::heightForWidth().
+
+    Even if you implement QWidget::heightForWidth(), it is still a good idea to
+    provide a reasonable sizeHint().
+
+    For further guidance when implementing these functions, see the
+    \e{Qt Quarterly} article
+    \l{http://qt.nokia.com/doc/qq/qq04-height-for-width.html}
+    {Trading Height for Width}.
+
+
+    \section1 Layout Issues
+
+    The use of rich text in a label widget can introduce some problems to the
+    layout of its parent widget. Problems occur due to the way rich text is
+    handled by Qt's layout managers when the label is word wrapped.
+
+    In certain cases the parent layout is put into QLayout::FreeResize mode,
+    meaning that it will not adapt the layout of its contents to fit inside
+    small sized windows, or even prevent the user from making the window too
+    small to be usable. This can be overcome by subclassing the problematic
+    widgets, and implementing suitable \l{QWidget::}{sizeHint()} and
+    \l{QWidget::}{minimumSizeHint()} functions.
+
+    In some cases, it is relevant when a layout is added to a widget. When
+    you set the widget of a QDockWidget or a QScrollArea (with
+    QDockWidget::setWidget() and QScrollArea::setWidget()), the layout must
+    already have been set on the widget. If not, the widget will not be
+    visible.
+
+
+    \section1 Manual Layout
+
+    If you are making a one-of-a-kind special layout, you can also make a
+    custom widget as described above. Reimplement QWidget::resizeEvent() to
+    calculate the required distribution of sizes and call
+    \l{QWidget::}{setGeometry()} on each child.
+
+    The widget will get an event of type QEvent::LayoutRequest when the
+    layout needs to be recalculated. Reimplement QWidget::event() to handle
+    QEvent::LayoutRequest events.
+
+
+    \section1 How to Write A Custom Layout Manager
+
+    An alternative to manual layout is to write your own layout manager by
+    subclassing QLayout. The \l{layouts/borderlayout}{Border Layout} and
+    \l{layouts/flowlayout}{Flow Layout} examples show how to do this.
+
+    Here we present an example in detail. The \c CardLayout class is inspired
+    by the Java layout manager of the same name. It lays out the items (widgets
+    or nested layouts) on top of each other, each item offset by
+    QLayout::spacing().
+
+    To write your own layout class, you must define the following:
+    \list
+        \o  A data structure to store the items handled by the layout. Each
+            item is a \link QLayoutItem QLayoutItem\endlink. We will use a
+            QList in this example.
+        \o  \l{QLayout::}{addItem()}, how to add items to the layout.
+        \o  \l{QLayout::}{setGeometry()}, how to perform the layout.
+        \o  \l{QLayout::}{sizeHint()}, the preferred size of the layout.
+        \o  \l{QLayout::}{itemAt()}, how to iterate over the layout.
+        \o  \l{QLayout::}{takeAt()}, how to remove items from the layout.
+    \endlist
+
+    In most cases, you will also implement \l{QLayout::}{minimumSize()}.
+
+
+    \section2 The Header File (\c card.h)
+
+    \snippet doc/src/snippets/code/doc_src_layout.qdoc 0
+
+
+    \section2 The Implementation File (\c card.cpp)
+
+    \snippet doc/src/snippets/code/doc_src_layout.qdoc 1
+
+    First we define \c{count()} to fetch the number of items in the list.
+
+    \snippet doc/src/snippets/code/doc_src_layout.qdoc 2
+
+    Then we define two functions that iterate over the layout: \c{itemAt()}
+    and \c{takeAt()}. These functions are used internally by the layout system
+    to handle deletion of widgets. They are also available for application
+    programmers. 
+
+    \c{itemAt()} returns the item at the given index. \c{takeAt()} removes the
+    item at the given index, and returns it. In this case we use the list index
+    as the layout index. In other cases where we have a more complex data
+    structure, we may have to spend more effort defining a linear order for the
+    items.
+
+    \snippet doc/src/snippets/code/doc_src_layout.qdoc 3
+
+    \c{addItem()} implements the default placement strategy for layout items.
+    This function must be implemented. It is used by QLayout::add(), by the
+    QLayout constructor that takes a layout as parent. If your layout has
+    advanced placement options that require parameters, you must provide extra
+    access functions such as the row and column spanning overloads of
+    QGridLayout::addItem(), QGridLayout::addWidget(), and
+    QGridLayout::addLayout().
+
+    \snippet doc/src/snippets/code/doc_src_layout.qdoc 4
+
+    The layout takes over responsibility of the items added. Since QLayoutItem
+    does not inherit QObject, we must delete the items manually. In the 
+    destructor, we remove each item from the list using \c{takeAt()}, and
+    then delete it.
+
+    \snippet doc/src/snippets/code/doc_src_layout.qdoc 5
+
+    The \c{setGeometry()} function actually performs the layout. The rectangle
+    supplied as an argument does not include \c{margin()}. If relevant, use
+    \c{spacing()} as the distance between items.
+
+    \snippet doc/src/snippets/code/doc_src_layout.qdoc 6
+
+    \c{sizeHint()} and \c{minimumSize()} are normally very similar in
+    implementation. The sizes returned by both functions should include
+    \c{spacing()}, but not \c{margin()}.
+
+    \snippet doc/src/snippets/code/doc_src_layout.qdoc 7
+
+
+    \section2 Further Notes
+
+    \list
+        \o  This custom layout does not handle height for width.
+        \o  We ignore QLayoutItem::isEmpty(); this means that the layout will
+            treat hidden widgets as visible.
+        \o  For complex layouts, speed can be greatly increased by caching
+            calculated values. In that case, implement
+            QLayoutItem::invalidate() to mark the cached data is dirty.
+        \o  Calling QLayoutItem::sizeHint(), etc. may be expensive. So, you
+            should store the value in a local variable if you need it again
+            later within in the same function.
+        \o  You should not call QLayoutItem::setGeometry() twice on the same
+            item in the same function. This call can be very expensive if the
+            item has several child widgets, because the layout manager must do
+            a complete layout every time. Instead, calculate the geometry and
+            then set it. (This does not only apply to layouts, you should do
+            the same if you implement your own resizeEvent(), for example.)
+    \endlist
+*/
+