| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \example itemviews/combowidgetmapper |
| \title Combo Widget Mapper Example |
| \ingroup examples-itemviews |
| \brief The Combo Widget Mapper example shows how to use a custom delegate to |
| map information from a model to specific widgets on a form. |
| |
| \image combowidgetmapper-example.png |
| |
| In the \l{Simple Widget Mapper Example}, we showed the basic use of a |
| widget mapper to relate data exposed by a model to simple input widgets |
| in a user interface. However, sometimes we want to use input widgets that |
| expose data as choices to the user, such as QComboBox, and we need a way |
| to relate their input to the values stored in the model. |
| |
| This example is very similar to the \l{Simple Widget Mapper Example}. |
| Again, we create a \c Window class with an almost identical user interface, |
| except that, instead of providing a spin box so that each person's age |
| can be entered, we provide a combo box to allow their addresses to be |
| classified as "Home", "Work" or "Other". |
| |
| \section1 Window Class Definition |
| |
| The class provides a constructor, a slot to keep the buttons up to date, |
| and a private function to set up the model: |
| |
| \snippet itemviews/combowidgetmapper/window.h Window definition |
| |
| In addition to the QDataWidgetMapper object and the controls used to make |
| up the user interface, we use a QStandardItemModel to hold our data and |
| a QStringListModel to hold information about the types of address that |
| can be applied to each person's data. |
| |
| \section1 Window Class Implementation |
| |
| The constructor of the \c Window class can be explained in three parts. |
| In the first part, we set up the widgets used for the user interface: |
| |
| \snippet itemviews/combowidgetmapper/window.cpp Set up widgets |
| |
| Note that we set up the mapping the combo box in the same way as for other |
| widgets, but that we apply its own model to it so that it will display |
| data from its own model, the \c typeModel, rather than from the model |
| containing data about each person. |
| |
| Next, we set up the widget mapper, relating each input widget to a column |
| in the model specified by the call to \l{QDataWidgetMapper::}{setModel()}: |
| |
| \snippet itemviews/combowidgetmapper/window.cpp Set up the mapper |
| |
| For the combo box, we pass an extra argument to tell the widget mapper |
| which property to relate to values from the model. As a result, the user |
| is able to select an item from the combo box, and the corresponding |
| value stored in the widget's \c currentIndex property will be stored in |
| the model. |
| |
| \omit |
| However, we also set a delegate on the mapper. As with \l{Delegate Classes}, |
| this changes the way that data is presented to the user. In this case, the |
| delegate acts as a proxy between the mapper and the input widgets, |
| translating the data into a suitable form for the combo box but not |
| interfering with the other input widgets. The implementation is shown later. |
| \endomit |
| |
| The rest of the constructor is very similar to that of the |
| \l{Simple Widget Mapper Example}: |
| |
| \snippet itemviews/combowidgetmapper/window.cpp Set up connections and layouts |
| |
| The model is initialized in the window's \c{setupModel()} function. Here, |
| we create a standard model with 5 rows and 3 columns. In each row, we |
| insert a name, address, and a value that indicates the type of address. |
| The address types are stored in a string list model. |
| |
| \snippet itemviews/combowidgetmapper/window.cpp Set up the model |
| |
| As we insert each row into the model, like a record in a database, we |
| store values that correspond to items in \c typeModel for each person's |
| address type. When the widget mapper reads these values from the final |
| column of each row, it will need to use them as references to values in |
| \c typeModel, as shown in the following diagram. This is where the |
| delegate is used. |
| |
| \image widgetmapper-combo-mapping.png |
| |
| We show the implementation of the \c{updateButtons()} slot for |
| completeness: |
| |
| \snippet itemviews/combowidgetmapper/window.cpp Slot for updating the buttons |
| |
| \omit |
| \section1 Delegate Class Definition and Implementation |
| |
| The delegate we use to mediate interaction between the widget mapper and |
| the input widgets is a small QItemDelegate subclass: |
| |
| \snippet itemviews/combowidgetmapper/delegate.h Delegate class definition |
| |
| This provides implementations of the two standard functions used to pass |
| data between editor widgets and the model (see the \l{Delegate Classes} |
| documentation for a more general description of these functions). |
| |
| Since we only provide an empty implementation of the constructor, we |
| concentrate on the other two functions. |
| |
| The \l{QItemDelegate::}{setEditorData()} implementation takes the data |
| referred to by the model index supplied and processes it according to |
| the presence of a \c currentIndex property in the editor widget: |
| |
| \snippet itemviews/combowidgetmapper/delegate.cpp setEditorData implementation |
| |
| If, like QComboBox, the editor widget has this property, it is set using |
| the value from the model. Since we are passing around QVariant values, |
| the strings stored in the model are automatically converted to the integer |
| values needed for the \c currentIndex property. |
| |
| As a result, instead of showing "0", "1" or "2" in the combo box, one of |
| its predefined set of items is shown. We call QItemDelegate::setEditorData() |
| for widgets without the \c currentIndex property. |
| |
| The \l{QItemDelegate::}{setModelData()} implementation performs the reverse |
| process, taking the value stored in the widget's \c currentIndex property |
| and storing it back in the model: |
| |
| \snippet itemviews/combowidgetmapper/delegate.cpp setModelData implementation |
| \endomit |
| |
| \section1 Summary and Further Reading |
| |
| The use of a separate model for the combo box provides a menu of choices |
| that are separate from the data stored in the main model. Using a named |
| mapping that relates the combo box's \c currentIndex property to a column |
| in the model effectively allows us to store a look-up value in the model. |
| |
| However, when reading the model outside the context of the widget mapper, |
| we need to know about the \c typeModel to make sense of these look-up |
| values. It would be useful to be able to store both the data and the |
| choices held by the \c typeModel in one place. |
| This is covered by the \l{SQL Widget Mapper Example}. |
| */ |