doc/src/examples/containerextension.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 designer/containerextension
       
    44     \title Container Extension Example
       
    45 
       
    46     The Container Extension example shows how to create a custom
       
    47     multi-page plugin for Qt Designer using the
       
    48     QDesignerContainerExtension class.
       
    49 
       
    50     \image containerextension-example.png
       
    51 
       
    52     To provide a custom widget that can be used with \QD, we need to
       
    53     supply a self-contained implementation. In this example we use a
       
    54     custom multi-page widget designed to show the container extension
       
    55     feature.
       
    56 
       
    57     An extension is an object which modifies the behavior of \QD. The
       
    58     QDesignerContainerExtension enables \QD to manage and manipulate a
       
    59     custom multi-page widget, i.e. adding and deleting pages to the
       
    60     widget.
       
    61 
       
    62     There are four available types of extensions in \QD:
       
    63 
       
    64     \list
       
    65         \o QDesignerMemberSheetExtension  provides an extension that allows
       
    66            you to manipulate a widget's member functions which is displayed
       
    67            when configuring connections using Qt Designer's mode for editing
       
    68            signals and slots.
       
    69         \o QDesignerPropertySheetExtension provides an extension that
       
    70            allows you to manipulate a widget's properties which is displayed
       
    71            in Qt Designer's property editor.
       
    72         \o QDesignerTaskMenuExtension provides an extension that allows
       
    73            you to add custom menu entries to \QD's task menu.
       
    74         \o QDesignerContainerExtension provides an extension that allows
       
    75            you to add (and delete) pages to a multi-page container plugin
       
    76            in \QD.
       
    77     \endlist
       
    78 
       
    79     You can use all the extensions following the same pattern as in
       
    80     this example, only replacing the respective extension base
       
    81     class. For more information, see the \l {QtDesigner Module}.
       
    82 
       
    83     The Container Extension example consists of four classes:
       
    84 
       
    85     \list
       
    86     \o \c MultiPageWidget is a custom container widget that lets the user
       
    87        manipulate and populate its pages, and navigate among these
       
    88        using a combobox.
       
    89     \o \c MultiPageWidgetPlugin exposes the \c MultiPageWidget class
       
    90        to \QD.
       
    91     \o \c MultiPageWidgetExtensionFactory creates a
       
    92        \c MultiPageWidgetContainerExtension object.
       
    93     \o \c MultiPageWidgetContainerExtension provides the container
       
    94        extension.
       
    95     \endlist
       
    96 
       
    97     The project file for custom widget plugins needs some additional
       
    98     information to ensure that they will work within \QD. For example,
       
    99     custom widget plugins rely on components supplied with \QD, and
       
   100     this must be specified in the project file that we use. We will
       
   101     first take a look at the plugin's project file.
       
   102 
       
   103     Then we will continue by reviewing the \c MultiPageWidgetPlugin
       
   104     class, and take a look at the \c MultiPageWidgetExtensionFactory
       
   105     and \c MultiPageWidgetContainerExtension classes. Finally, we will
       
   106     take a quick look at the \c MultiPageWidget class definition.
       
   107 
       
   108     \section1 The Project File: containerextension.pro
       
   109 
       
   110     The project file must contain some additional information to
       
   111     ensure that the plugin will work as expected:
       
   112 
       
   113     \snippet examples/designer/containerextension/containerextension.pro 0
       
   114     \snippet examples/designer/containerextension/containerextension.pro 1
       
   115 
       
   116     The \c TEMPLATE variable's value makes \c qmake create the custom
       
   117     widget as a library. Later, we will ensure that the widget will be
       
   118     recognized as a plugin by Qt by using the Q_EXPORT_PLUGIN2() macro
       
   119     to export the relevant widget information.
       
   120 
       
   121     The \c CONFIG variable contains two values, \c designer and \c
       
   122     plugin:
       
   123 
       
   124     \list
       
   125         \o \c designer: Since custom widgets plugins rely on components
       
   126            supplied with \QD, this value ensures that our plugin links against
       
   127            \QD's library (\c libQtDesigner.so).
       
   128 
       
   129         \o \c plugin: We also need to ensure that \c qmake considers the
       
   130            custom widget a \e plugin library.
       
   131     \endlist
       
   132 
       
   133     When Qt is configured to build in both debug and release modes,
       
   134     \QD will be built in release mode.  When this occurs, it is
       
   135     necessary to ensure that plugins are also built in release
       
   136     mode. For that reason we add a \c debug_and_release value to the
       
   137     \c CONFIG variable. Otherwise, if a plugin is built in a mode that
       
   138     is incompatible with \QD, it won't be loaded and installed.
       
   139 
       
   140     The header and source files for the widget are declared in the
       
   141     usual way:
       
   142 
       
   143     \snippet examples/designer/containerextension/containerextension.pro 2
       
   144 
       
   145     We provide an implementation of the plugin interface so that \QD
       
   146     can use the custom widget. In this particular example we also
       
   147     provide implementations of the container extension interface and
       
   148     the extension factory.
       
   149 
       
   150     It is important to ensure that the plugin is installed in a
       
   151     location that is searched by \QD. We do this by specifying a
       
   152     target path for the project and adding it to the list of items to
       
   153     install:
       
   154 
       
   155     \snippet doc/src/snippets/code/doc_src_examples_containerextension.qdoc 0
       
   156 
       
   157     The container extension is created as a library, and will be
       
   158     installed alongside the other \QD plugins when the project is
       
   159     installed (using \c{make install} or an equivalent installation
       
   160     procedure).
       
   161 
       
   162     Note that if you want the plugins to appear in a Visual Studio
       
   163     integration, the plugins must be built in release mode and their
       
   164     libraries must be copied into the plugin directory in the install
       
   165     path of the integration (for an example, see \c {C:/program
       
   166     files/trolltech as/visual studio integration/plugins}).
       
   167 
       
   168     For more information about plugins, see the \l {How to Create Qt
       
   169     Plugins} documentation.
       
   170 
       
   171     \section1 MultiPageWidgetPlugin Class Definition
       
   172 
       
   173     The \c MultiPageWidgetPlugin class exposes the \c MultiPageWidget
       
   174     class to \QD. Its definition is similar to the \l
       
   175     {designer/customwidgetplugin}{Custom Widget Plugin} example's
       
   176     plugin class which is explained in detail. The parts of the class
       
   177     definition that is specific to this particular custom widget is
       
   178     the class name and a couple of private slots:
       
   179 
       
   180     \snippet examples/designer/containerextension/multipagewidgetplugin.h 0
       
   181 
       
   182     The plugin class provides \QD with basic information about our
       
   183     plugin, such as its class name and its include file. Furthermore
       
   184     it knows how to create instances of the \c MultiPageWidget widget.
       
   185     \c MultiPageWidgetPlugin also defines the \l
       
   186     {QDesignerCustomWidgetInterface::initialize()}{initialize()}
       
   187     function which is called after the plugin is loaded into \QD. The
       
   188     function's QDesignerFormEditorInterface parameter provides the
       
   189     plugin with a gateway to all of \QD's API's.
       
   190 
       
   191     In the case of a multipage widget such as ours, we must also implement
       
   192     two private slots, currentIndexChanged() and pageTitleChanged(),
       
   193     to be able to update \QD's property editor whenever the user views
       
   194     another page or changes one of the page titles. To be able to give
       
   195     each page their own title, we have chosen to use the
       
   196     QWidget::windowTitle property to store the page title (for more
       
   197     information see the MultiPageWidget class \l
       
   198     {designer/containerextension/multipagewidget.cpp}{implementation}). Note
       
   199     that currently there is no way of adding a custom property (e.g.,
       
   200     a page title) to the pages without using a predefined property as
       
   201     placeholder.
       
   202 
       
   203     The \c MultiPageWidgetPlugin class inherits from both QObject and
       
   204     QDesignerCustomWidgetInterface. It is important to remember, when
       
   205     using multiple inheritance, to ensure that all the interfaces
       
   206     (i.e. the classes that doesn't inherit Q_OBJECT) are made known to
       
   207     the meta object system using the Q_INTERFACES() macro. This
       
   208     enables \QD to use \l qobject_cast() to query for supported
       
   209     interfaces using nothing but a QObject pointer.
       
   210 
       
   211     \section1 MultiPageWidgetPlugin Class Implementation
       
   212 
       
   213     The MultiPageWidgetPlugin class implementation is in most parts
       
   214     equivalent to the \l {designer/customwidgetplugin}{Custom Widget
       
   215     Plugin} example's plugin class:
       
   216 
       
   217     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 0
       
   218     \codeline
       
   219     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 3
       
   220 
       
   221     One of the functions that differ is the isContainer() function
       
   222     which returns true in this example since our custom widget is
       
   223     intended to be used as a container.
       
   224 
       
   225     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 1
       
   226 
       
   227     Another function that differ is the function creating our custom widget:
       
   228 
       
   229     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 2
       
   230 
       
   231     In addition to create and return the widget, we connect our custom
       
   232     container widget's currentIndexChanged() signal to the plugin's
       
   233     currentIndexChanged() slot to ensure that \QD's property editor is
       
   234     updated whenever the user views another page. We also connect the
       
   235     widget's pageTitleChanged() signal to the plugin's
       
   236     pageTitleChanged() slot.
       
   237 
       
   238     The currentIndexChanged() slot is called whenever our custom
       
   239     widget's currentIndexChanged() \e signal is emitted, i.e. whenever
       
   240     the user views another page:
       
   241 
       
   242     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 8
       
   243 
       
   244     First, we retrieve the object emitting the signal using the
       
   245     QObject::sender() and qobject_cast() functions. If it's called in
       
   246     a slot activated by a signal, QObject::sender() returns a pointer
       
   247     to the object that sent the signal; otherwise it returns 0.
       
   248 
       
   249     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 9
       
   250 
       
   251     Once we have the widget we can update the property editor. \QD
       
   252     uses the QDesignerPropertySheetExtension class to feed its
       
   253     property editor, and whenever a widget is selected in its
       
   254     workspace, Qt Designer will query for the widget's property sheet
       
   255     extension and update the property editor.
       
   256 
       
   257     So what we want to achieve is to notify \QD that our widget's \e
       
   258     internal selection has changed: First we use the static
       
   259     QDesignerFormWindowInterface::findFormWindow() function to
       
   260     retrieve the QDesignerFormWindowInterface object containing the
       
   261     widget. The QDesignerFormWindowInterface class allows you to query
       
   262     and manipulate form windows appearing in Qt Designer's
       
   263     workspace. Then, all we have to do is to emit its \l
       
   264     {QDesignerFormWindowInterface::emitSelectionChanged()}{emitSelectionChanged()}
       
   265     signal, forcing an update of the property editor.
       
   266 
       
   267     When changing a page title a generic refresh of the property
       
   268     editor is not enough because it is actually the page's property
       
   269     extension that needs to be updated. For that reason we need to
       
   270     access the QDesignerPropertySheetExtension object for the page
       
   271     which title we want to change. The QDesignerPropertySheetExtension
       
   272     class also allows you to manipulate a widget's properties, but to
       
   273     get hold of the extension we must first retrieve access to \QD's
       
   274     extension manager:
       
   275 
       
   276     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 10
       
   277     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 11
       
   278 
       
   279     Again we first retrieve the widget emitting the signal, using the
       
   280     QObject::sender() and qobject_cast() functions. Then we retrieve
       
   281     the current page from the widget that emitted the signal, and we
       
   282     use the static QDesignerFormWindowInterface::findFormWindow()
       
   283     function to retrieve the form containing our widget.
       
   284 
       
   285     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 12
       
   286 
       
   287     Now that we have the form window, the QDesignerFormWindowInterface
       
   288     class provides the \l
       
   289     {QDesignerFormWindowInterface::core()}{core()} function which
       
   290     returns the current QDesignerFormEditorInterface object. The
       
   291     QDesignerFormEditorInterface class allows you to access Qt
       
   292     Designer's various components. In particular, the
       
   293     QDesignerFormEditorInterface::extensionManager() function returns
       
   294     a reference to the current extension manager.
       
   295 
       
   296     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 13
       
   297 
       
   298     Once we have the extension manager we can update the extension
       
   299     sheet: First we retrieve the property extension for the page which
       
   300     title we want to change, using the qt_extension() function.  Then
       
   301     we retrieve the index for the page title using the
       
   302     QDesignerPropertySheetExtension::indexOf() function. As previously
       
   303     mentioned, we have chosen to use the QWidget::windowTitle property
       
   304     to store the page title (for more information see the
       
   305     MultiPageWidget class \l
       
   306     {designer/containerextension/multipagewidget.cpp}{implementation}).
       
   307     Finally, we implicitly force an update of the page's property
       
   308     sheet by calling the
       
   309     QDesignerPropertySheetExtension::setChanged() function.
       
   310 
       
   311     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 4
       
   312 
       
   313     Note also the initialize() function: The \c initialize() function
       
   314     takes a QDesignerFormEditorInterface object as argument.
       
   315 
       
   316     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 5
       
   317 
       
   318     When creating extensions associated with custom widget plugins, we
       
   319     need to access \QD's current extension manager which we retrieve
       
   320     from the QDesignerFormEditorInterface parameter.
       
   321 
       
   322     In addition to allowing you to manipulate a widget's properties,
       
   323     the QExtensionManager class provides extension management
       
   324     facilities for \QD. Using \QD's current extension manager you can
       
   325     retrieve the extension for a given object. You can also register
       
   326     and unregister an extension for a given object. Remember that an
       
   327     extension is an object which modifies the behavior of \QD.
       
   328 
       
   329     When registrering an extension, it is actually the associated
       
   330     extension factory that is registered. In \QD, extension factories
       
   331     are used to look up and create named extensions as they are
       
   332     required. So, in this example, the container extension itself is
       
   333     not created until \QD must know whether the associated widget is a
       
   334     container, or not.
       
   335 
       
   336     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 6
       
   337 
       
   338     We create a \c MultiPageWidgetExtensionFactory object that we
       
   339     register using \QD's current \l {QExtensionManager}{extension
       
   340     manager} retrieved from the QDesignerFormEditorInterface
       
   341     parameter. The first argument is the newly created factory and the
       
   342     second argument is an extension identifier which is a string. The
       
   343     \c Q_TYPEID() macro simply convert the string into a
       
   344     QLatin1String.
       
   345 
       
   346     The \c MultiPageWidgetExtensionFactory class is a subclass of
       
   347     QExtensionFactory. When \QD must know whether a widget is a
       
   348     container, or not, \QD's extension manager will run through all
       
   349     its registered factories invoking the first one which is able to
       
   350     create a container extension for that widget. This factory will in
       
   351     turn create a \c MultiPageWidgetExtension object.
       
   352 
       
   353     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 7
       
   354 
       
   355     Finally, take a look at the \c domXml() function. This function
       
   356     includes default settings for the widget in the standard XML
       
   357     format used by \QD. In this case, we specify the container's first
       
   358     page; any inital pages of a multi-page widget must be specified
       
   359     within this function.
       
   360 
       
   361     \snippet examples/designer/containerextension/multipagewidgetplugin.cpp 14
       
   362 
       
   363     Remember to use the Q_EXPORT_PLUGIN2() macro to export the
       
   364     MultiPageWidgetPlugin class for use with Qt's plugin handling
       
   365     classes: This macro ensures that \QD can access and construct the
       
   366     custom widget. Without this macro, there is no way for \QD to use
       
   367     the widget.
       
   368 
       
   369     \section1 MultiPageWidgetExtensionFactory Class Definition
       
   370 
       
   371     The \c MultiPageWidgetExtensionFactory class inherits QExtensionFactory
       
   372     which provides a standard extension factory for \QD.
       
   373 
       
   374     \snippet examples/designer/containerextension/multipagewidgetextensionfactory.h 0
       
   375 
       
   376     The subclass's purpose is to reimplement the
       
   377     QExtensionFactory::createExtension() function, making it able to
       
   378     create a \c MultiPageWidget container extension.
       
   379 
       
   380 
       
   381     \section1 MultiPageWidgetExtensionFactory Class Implementation
       
   382 
       
   383     The class constructor simply calls the QExtensionFactory base
       
   384     class constructor:
       
   385 
       
   386     \snippet examples/designer/containerextension/multipagewidgetextensionfactory.cpp 0
       
   387 
       
   388     As described above, the factory is invoked when \QD must know
       
   389     whether the associated widget is a container, or not.
       
   390 
       
   391     \snippet examples/designer/containerextension/multipagewidgetextensionfactory.cpp 1
       
   392 
       
   393     \QD's behavior is the same whether the requested extension is
       
   394     associated with a container, a member sheet, a property sheet or a
       
   395     task menu: Its extension manager runs through all its registered
       
   396     extension factories calling \c createExtension() for each until
       
   397     one responds by creating the requested extension.
       
   398 
       
   399     So the first thing we do in \c
       
   400     MultiPageWidgetExtensionFactory::createExtension() is to check if
       
   401     the QObject, for which the extension is requested, is in fact a \c
       
   402     MultiPageWidget object. Then we check if the requested extension
       
   403     is a container extension.
       
   404 
       
   405     If the object is a MultiPageWidget requesting a container
       
   406     extension, we create and return a \c MultiPageWidgetExtension
       
   407     object. Otherwise, we simply return a null pointer, allowing \QD's
       
   408     extension manager to continue its search through the registered
       
   409     factories.
       
   410 
       
   411 
       
   412     \section1 MultiPageWidgetContainerExtension Class Definition
       
   413 
       
   414     The \c MultiPageWidgetContainerExtension class inherits
       
   415     QDesignerContainerExtension which allows you to add (and delete)
       
   416     pages to a multi-page container plugin in \QD.
       
   417 
       
   418     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.h 0
       
   419 
       
   420     It is important to recognize that the QDesignerContainerExtension
       
   421     class only is intended to provide \QD access to your custom
       
   422     multi-page widget's functionality; your custom multi-page widget
       
   423     must implement functionality corresponding to the extension's
       
   424     functions.
       
   425 
       
   426     Note also that we implement a constructor that takes \e two
       
   427     arguments: the parent widget, and the \c MultiPageWidget object
       
   428     for which the task menu is requested.
       
   429 
       
   430     QDesignerContainerExtension provides a couple of menu entries in
       
   431     \QD's task menu by default, enabling the user to add or delete
       
   432     pages to the associated custom multi-page widget in \QD's
       
   433     workspace.
       
   434 
       
   435     \section1 MultiPageWidgetContainerExtension Class Implementation
       
   436 
       
   437     In the constructor we save the reference to the \c MultiPageWidget
       
   438     object sent as parameter, i.e the widget associated with the
       
   439     extension. We will need this later to access the custom multi-page
       
   440     widget performing the requested actions.
       
   441 
       
   442     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 0
       
   443 
       
   444     To fully enable \QD to manage and manipulate your custom
       
   445     multi-page widget, you must reimplement all the functions of
       
   446     QDesignerContainerExtension:
       
   447 
       
   448     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 1
       
   449     \codeline
       
   450     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 2
       
   451     \codeline
       
   452     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 3
       
   453 
       
   454     You must reimplement \l
       
   455     {QDesignerContainerExtension::addWidget()}{addWidget()} adding a
       
   456     given page to the container, \l
       
   457     {QDesignerContainerExtension::count()}{count()} returning the
       
   458     number of pages in the container, and \l
       
   459     {QDesignerContainerExtension::currentIndex()}{currentIndex()}
       
   460     returning the index of the currently selected page.
       
   461 
       
   462     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 4
       
   463     \codeline
       
   464     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 5
       
   465     \codeline
       
   466     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 6
       
   467     \codeline
       
   468     \snippet examples/designer/containerextension/multipagewidgetcontainerextension.cpp 7
       
   469 
       
   470     You must reimplement \l
       
   471     {QDesignerContainerExtension::insertWidget()}{insertWidget()}
       
   472     adding a given page to the container at a given index, \l
       
   473     {QDesignerContainerExtension::remove()}{remove()} deleting the
       
   474     page at a given index, \l
       
   475     {QDesignerContainerExtension::setCurrentIndex()}{setCurrentIndex()}
       
   476     setting the index of the currently selected page, and finally \l
       
   477     {QDesignerContainerExtension::widget()}{widget()} returning the
       
   478     page at a given index.
       
   479 
       
   480     \section1 MultiPageWidget Class Definition
       
   481 
       
   482     The MultiPageWidget class is a custom container widget that lets
       
   483     the user manipulate and populate its pages, and navigate among
       
   484     these using a combobox.
       
   485 
       
   486     \snippet examples/designer/containerextension/multipagewidget.h 0
       
   487 
       
   488     The main detail to observe is that your custom multi-page widget
       
   489     must implement functionality corresponding to the
       
   490     QDesignerContainerExtension's member functions since the
       
   491     QDesignerContainerExtension class only is intended to provide Qt
       
   492     Designer access to your custom multi-page widget's functionality.
       
   493 
       
   494     In addition, we declare the \c currentIndex and \c pageTitle
       
   495     properties, and their associated set and get functions. By
       
   496     declaring these attributes as properties, we allow \QD to manage
       
   497     them in the same way it manages the properties the MultiPageWidget
       
   498     widget inherits from QWidget and QObject, for example featuring
       
   499     the property editor.
       
   500 
       
   501     Note the \c STORED attribute in the declaration of the \c
       
   502     pageTitle property: The \c STORED attribute indicates persistence,
       
   503     i.e. it declares whether the property's value must be remembered
       
   504     when storing an object's state. As mentioned above, we have chosen
       
   505     to store the page title using the QWidget::windowTitle property to
       
   506     be able to give each page their own title. For that reason the \c
       
   507     pageTitle property is a "fake" property, provided for editing
       
   508     purposes, and doesn't need to be stored.
       
   509 
       
   510     We must also implement and emit the currentIndexChanged() and
       
   511     pageTitleChanged() signals to ensure that \QD's property editor is
       
   512     updated whenever the user views another page or changes one of the
       
   513     page titles.
       
   514 
       
   515     See the MultiPageWidget class \l
       
   516     {designer/containerextension/multipagewidget.cpp}{implementation}
       
   517     for more details.
       
   518 */