doc/src/examples/sqlwidgetmapper.qdoc
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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     \example sql/sqlwidgetmapper
       
    44     \title SQL Widget Mapper Example
       
    45 
       
    46     The SQL Widget Mapper example shows how to use a map information from a
       
    47     database to widgets on a form.
       
    48 
       
    49     \image sql-widget-mapper.png
       
    50 
       
    51     In the \l{Combo Widget Mapper Example}, we showed how to use a named
       
    52     mapping between a widget mapper and a QComboBox widget with a special
       
    53     purpose model to relate values in the model to a list of choices.
       
    54 
       
    55     Again, we create a \c Window class with an almost identical user interface,
       
    56     providing a combo box to allow their addresses to be classified as "Home",
       
    57     "Work" or "Other". However, instead of using a separate model to hold these
       
    58     address types, we use one database table to hold the example data and
       
    59     another to hold the address types. In this way, we store all the
       
    60     information in the same place.
       
    61 
       
    62     \section1 Window Class Definition
       
    63 
       
    64     The class provides a constructor, a slot to keep the buttons up to date,
       
    65     and a private function to set up the model:
       
    66 
       
    67     \snippet examples/sql/sqlwidgetmapper/window.h Window definition
       
    68 
       
    69     In addition to the QDataWidgetMapper object and the controls used to make
       
    70     up the user interface, we use a QStandardItemModel to hold our data and
       
    71     a QStringListModel to hold information about the types of address that
       
    72     can be applied to each person's data.
       
    73 
       
    74     \section1 Window Class Implementation
       
    75 
       
    76     The first act performed by the \c Window class constructor is to set up
       
    77     the model used to hold the example data. Since this is a key part of the
       
    78     example, we will look at this first.
       
    79 
       
    80     The model is initialized in the window's \c{setupModel()} function. Here,
       
    81     we create a SQLite database containing a "person" table with primary key,
       
    82     name, address and type fields.
       
    83 
       
    84     \snippet examples/sql/sqlwidgetmapper/window.cpp Set up the main table
       
    85 
       
    86     On each row of the table, we insert default values for these fields,
       
    87     including values for the address types that correspond to the address
       
    88     types are stored in a separate table.
       
    89 
       
    90     \image widgetmapper-sql-mapping-table.png
       
    91 
       
    92     We create an "addresstype" table containing the identifiers used in the
       
    93     "person" table and the corresponding strings:
       
    94 
       
    95     \snippet examples/sql/sqlwidgetmapper/window.cpp Set up the address type table
       
    96 
       
    97     The "typeid" field in the "person" table is related to the contents of
       
    98     the "addresstype" table via a relation in a QSqlRelationalTableModel.
       
    99     This kind of model performs all the necessary work to store the data in
       
   100     a database and also allows any relations to be used as models in their
       
   101     own right.
       
   102 
       
   103     In this case, we have defined a relation for the "typeid" field in the
       
   104     "person" table that relates it to the "id" field in the "addresstype"
       
   105     table and which causes the contents of the "description" field to be
       
   106     used wherever the "typeid" is presented to the user. (See the
       
   107     QSqlRelationalTableModel::setRelation() documentation for details.)
       
   108 
       
   109     \image widgetmapper-sql-mapping.png
       
   110 
       
   111     The constructor of the \c Window class can be explained in three parts.
       
   112     In the first part, we set up the model used to hold the data, then we set
       
   113     up the widgets used for the user interface:
       
   114 
       
   115     \snippet examples/sql/sqlwidgetmapper/window.cpp Set up widgets
       
   116 
       
   117     We obtain a model for the combo box from the main model, based on the
       
   118     relation we set up for the "typeid" field. The call to the combo box's
       
   119     \l{QComboBox::}{setModelColumn()} selects the field in the field in the
       
   120     model to display.
       
   121 
       
   122     Note that this approach is similar to the one used in the
       
   123     \l{Combo Widget Mapper Example} in that we set up a model for the
       
   124     combo box. However, in this case, we obtain a model based on a relation
       
   125     in the QSqlRelationalTableModel rather than create a separate one.
       
   126 
       
   127     Next, we set up the widget mapper, relating each input widget to a field
       
   128     in the model:
       
   129 
       
   130     \snippet examples/sql/sqlwidgetmapper/window.cpp Set up the mapper
       
   131 
       
   132     For the combo box, we already know the index of the field in the model
       
   133     from the \c{setupModel()} function. We use a QSqlRelationalDelegate as
       
   134     a proxy between the mapper and the input widgets to match up the "typeid"
       
   135     values in the model with those in the combo box's model and populate the
       
   136     combo box with descriptions rather than integer values.
       
   137 
       
   138     As a result, the user is able to select an item from the combo box,
       
   139     and the associated value is written back to the model.
       
   140 
       
   141     The rest of the constructor is very similar to that of the
       
   142     \l{Simple Widget Mapper Example}:
       
   143 
       
   144     \snippet examples/sql/sqlwidgetmapper/window.cpp Set up connections and layouts
       
   145 
       
   146     We show the implementation of the \c{updateButtons()} slot for
       
   147     completeness:
       
   148 
       
   149     \snippet examples/sql/sqlwidgetmapper/window.cpp Slot for updating the buttons
       
   150 
       
   151     \omit
       
   152     \section1 Delegate Class Definition and Implementation
       
   153 
       
   154     The delegate we use to mediate interaction between the widget mapper and
       
   155     the input widgets is a small QItemDelegate subclass:
       
   156 
       
   157     \snippet examples/sql/sqlwidgetmapper/delegate.h Delegate class definition
       
   158 
       
   159     This provides implementations of the two standard functions used to pass
       
   160     data between editor widgets and the model (see the \l{Delegate Classes}
       
   161     documentation for a more general description of these functions).
       
   162 
       
   163     Since we only provide an empty implementation of the constructor, we
       
   164     concentrate on the other two functions.
       
   165 
       
   166     The \l{QItemDelegate::}{setEditorData()} implementation takes the data
       
   167     referred to by the model index supplied and processes it according to
       
   168     the presence of a \c currentIndex property in the editor widget:
       
   169 
       
   170     \snippet examples/sql/sqlwidgetmapper/delegate.cpp setEditorData implementation
       
   171 
       
   172     If, like QComboBox, the editor widget has this property, it is set using
       
   173     the value from the model. Since we are passing around QVariant values,
       
   174     the strings stored in the model are automatically converted to the integer
       
   175     values needed for the \c currentIndex property.
       
   176 
       
   177     As a result, instead of showing "0", "1" or "2" in the combo box, one of
       
   178     its predefined set of items is shown. We call QItemDelegate::setEditorData()
       
   179     for widgets without the \c currentIndex property.
       
   180 
       
   181     The \l{QItemDelegate::}{setModelData()} implementation performs the reverse
       
   182     process, taking the value stored in the widget's \c currentIndex property
       
   183     and storing it back in the model:
       
   184 
       
   185     \snippet examples/sql/sqlwidgetmapper/delegate.cpp setModelData implementation
       
   186     \endomit
       
   187 
       
   188     \section1 Summary and Further Reading
       
   189 
       
   190     The use of a separate model for the combo box and a special delegate for the
       
   191     widget mapper allows us to present a menu of choices to the user. Although
       
   192     the choices are stored in the same database as the user's data, they are held
       
   193     in a separate table. Using this approach, we can reconstructed complete records
       
   194     at a later time while using database features appropriately.
       
   195 
       
   196     If SQL models are not being used, it is still possible to use more than
       
   197     one model to present choices to the user. This is covered by the
       
   198     \l{Combo Widget Mapper Example}.
       
   199 */