diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2012-09-18 20:32:53 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-09-21 19:59:06 +0200 |
commit | d16c565ca6a55788435c52ad45647eda67854d80 (patch) | |
tree | 17e2c192b412e4959d422c1691e74ad172601ff7 /examples/sql | |
parent | 53373bdd9faf343611796e401805327e6de47586 (diff) |
Move opengl/wid/net example docs to proper folders.
Change-Id: I846439a9cf7ad965ed27a00f98dbc4ff97abe73b
Reviewed-by: Jerome Pasion <jerome.pasion@digia.com>
Reviewed-by: Martin Smith <martin.smith@digia.com>
Diffstat (limited to 'examples/sql')
18 files changed, 1106 insertions, 0 deletions
diff --git a/examples/sql/doc/images/cachedtable-example.png b/examples/sql/doc/images/cachedtable-example.png Binary files differnew file mode 100644 index 0000000000..db770dfdf2 --- /dev/null +++ b/examples/sql/doc/images/cachedtable-example.png diff --git a/examples/sql/doc/images/drilldown-example.png b/examples/sql/doc/images/drilldown-example.png Binary files differnew file mode 100644 index 0000000000..68353f704a --- /dev/null +++ b/examples/sql/doc/images/drilldown-example.png diff --git a/examples/sql/doc/images/masterdetail-example.png b/examples/sql/doc/images/masterdetail-example.png Binary files differnew file mode 100644 index 0000000000..bc282b7a78 --- /dev/null +++ b/examples/sql/doc/images/masterdetail-example.png diff --git a/examples/sql/doc/images/querymodel-example.png b/examples/sql/doc/images/querymodel-example.png Binary files differnew file mode 100644 index 0000000000..908d500e1f --- /dev/null +++ b/examples/sql/doc/images/querymodel-example.png diff --git a/examples/sql/doc/images/relationaltablemodel-example.png b/examples/sql/doc/images/relationaltablemodel-example.png Binary files differnew file mode 100644 index 0000000000..44fc858562 --- /dev/null +++ b/examples/sql/doc/images/relationaltablemodel-example.png diff --git a/examples/sql/doc/images/sql-widget-mapper.png b/examples/sql/doc/images/sql-widget-mapper.png Binary files differnew file mode 100644 index 0000000000..dfa64aba9e --- /dev/null +++ b/examples/sql/doc/images/sql-widget-mapper.png diff --git a/examples/sql/doc/images/sqlbrowser-demo.png b/examples/sql/doc/images/sqlbrowser-demo.png Binary files differnew file mode 100644 index 0000000000..101ec5a0a3 --- /dev/null +++ b/examples/sql/doc/images/sqlbrowser-demo.png diff --git a/examples/sql/doc/images/tablemodel-example.png b/examples/sql/doc/images/tablemodel-example.png Binary files differnew file mode 100644 index 0000000000..3ae2a8c05c --- /dev/null +++ b/examples/sql/doc/images/tablemodel-example.png diff --git a/examples/sql/doc/images/widgetmapper-sql-mapping-table.png b/examples/sql/doc/images/widgetmapper-sql-mapping-table.png Binary files differnew file mode 100644 index 0000000000..98734b34b6 --- /dev/null +++ b/examples/sql/doc/images/widgetmapper-sql-mapping-table.png diff --git a/examples/sql/doc/images/widgetmapper-sql-mapping.png b/examples/sql/doc/images/widgetmapper-sql-mapping.png Binary files differnew file mode 100644 index 0000000000..88718c6a8b --- /dev/null +++ b/examples/sql/doc/images/widgetmapper-sql-mapping.png diff --git a/examples/sql/doc/src/cachedtable.qdoc b/examples/sql/doc/src/cachedtable.qdoc new file mode 100644 index 0000000000..863cbce61e --- /dev/null +++ b/examples/sql/doc/src/cachedtable.qdoc @@ -0,0 +1,197 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example cachedtable + \title Cached Table Example + + The Cached Table example shows how a table view can be used to access a database, + caching any changes to the data until the user explicitly submits them using a + push button. + + \image cachedtable-example.png + + The example consists of a single class, \c TableEditor, which is a + custom dialog widget that allows the user to modify data stored in + a database. We will first review the class definiton and how to + use the class, then we will take a look at the implementation. + + \section1 TableEditor Class Definition + + The \c TableEditor class inherits QDialog making the table editor + widget a top-level dialog window. + + \snippet cachedtable/tableeditor.h 0 + + The \c TableEditor constructor takes two arguments: The first is a + pointer to the parent widget and is passed on to the base class + constructor. The other is a reference to the database table the \c + TableEditor object will operate on. + + Note the QSqlTableModel variable declaration: As we will see in + this example, the QSqlTableModel class can be used to provide data + to view classes such as QTableView. The QSqlTableModel class + provides an editable data model making it possible to read and + write database records from a single table. It is build on top of + the lower-level QSqlQuery class which provides means of executing + and manipulating SQL statements. + + We are also going to show how a table view can be used to cache + any changes to the data until the user explicitly requests to + submit them. For that reason we need to declare a \c submit() slot + in additon to the model and the editor's buttons. + + \table 100% + \header \li Connecting to a Database + \row + \li + + Before we can use the \c TableEditor class, we must create a + connection to the database containing the table we want to edit: + + \snippet cachedtable/main.cpp 0 + + The \c createConnection() function is a helper function provided + for convenience. It is defined in the \c connection.h file which + is located in the \c sql example directory (all the examples in + the \c sql directory use this function to connect to a database). + + \snippet connection.h 0 + + The \c createConnection function opens a connection to an + in-memory SQLITE database and creates a test table. If you want + to use another database, simply modify this function's code. + \endtable + + \section1 TableEditor Class Implementation + + The class implementation consists of only two functions, the + constructor and the \c submit() slot. In the constructor we create + and customize the data model and the various window elements: + + \snippet cachedtable/tableeditor.cpp 0 + + First we create the data model and set the SQL database table we + want the model to operate on. Note that the + QSqlTableModel::setTable() function does not select data from the + table; it only fetches its field information. For that reason we + call the QSqlTableModel::select() function later on, populating + the model with data from the table. The selection can be + customized by specifying filters and sort conditions (see the + QSqlTableModel class documentation for more details). + + We also set the model's edit strategy. The edit strategy dictates + when the changes done by the user in the view, are actually + applied to the database. Since we want to cache the changes in the + table view (i.e. in the model) until the user explicitly submits + them, we choose the QSqlTableModel::OnManualSubmit strategy. The + alternatives are QSqlTableModel::OnFieldChange and + QSqlTableModel::OnRowChange. + + Finally, we set up the labels displayed in the view header using + the \l {QSqlQueryModel::setHeaderData()}{setHeaderData()} function + that the model inherits from the QSqlQueryModel class. + + \snippet cachedtable/tableeditor.cpp 1 + + Then we create a table view. The QTableView class provides a + default model/view implementation of a table view, i.e. it + implements a table view that displays items from a model. It also + allows the user to edit the items, storing the changes in the + model. To create a read only view, set the proper flag using the + \l {QAbstractItemView::editTriggers}{editTriggers} property the + view inherits from the QAbstractItemView class. + + To make the view present our data, we pass our model to the view + using the \l {QAbstractItemView::setModel()}{setModel()} function. + + \snippet cachedtable/tableeditor.cpp 2 + + The \c {TableEditor}'s buttons are regular QPushButton objects. We + add them to a button box to ensure that the buttons are presented + in a layout that is appropriate to the current widget style. The + rationale for this is that dialogs and message boxes typically + present buttons in a layout that conforms to the interface + guidelines for that platform. Invariably, different platforms have + different layouts for their dialogs. QDialogButtonBox allows a + developer to add buttons to it and will automatically use the + appropriate layout for the user's desktop environment. + + Most buttons for a dialog follow certain roles. When adding a + button to a button box using the \l + {QDialogButtonBox}{addButton()} function, the button's role must + be specified using the QDialogButtonBox::ButtonRole + enum. Alternatively, QDialogButtonBox provides several standard + buttons (e.g. \uicontrol OK, \uicontrol Cancel, \uicontrol Save) that you can + use. They exist as flags so you can OR them together in the + constructor. + + \snippet cachedtable/tableeditor.cpp 3 + + We connect the \uicontrol Quit button to the table editor's \l + {QWidget::close()}{close()} slot, and the \uicontrol Submit button to + our private \c submit() slot. The latter slot will take care of + the data transactions. Finally, we connect the \uicontrol Revert button + to our model's \l {QSqlTableModel::revertAll()}{revertAll()} slot, + reverting all pending changes (i.e., restoring the original data). + + \snippet cachedtable/tableeditor.cpp 4 + + In the end we add the button box and the table view to a layout, + install the layout on the table editor widget, and set the + editor's window title. + + \snippet cachedtable/tableeditor.cpp 5 + + The \c submit() slot is called whenever the users hit the \uicontrol + Submit button to save their changes. + + First, we begin a transaction on the database using the + QSqlDatabase::transaction() function. A database transaction is a + unit of interaction with a database management system or similar + system that is treated in a coherent and reliable way independent + of other transactions. A pointer to the used database can be + obtained using the QSqlTableModel::database() function. + + Then, we try to submit all the pending changes, i.e. the model's + modified items. If no error occurs, we commit the transaction to + the database using the QSqlDatabase::commit() function (note that + on some databases, this function will not work if there is an + active QSqlQuery on the database). Otherwise we perform a rollback + of the transaction using the QSqlDatabase::rollback() function and + post a warning to the user. + + \table 100% + \row + \li + \b {See also:} + + A complete list of Qt's SQL \l {Database Classes}, and the \l + {Model/View Programming} documentation. + + \endtable +*/ diff --git a/examples/sql/doc/src/drilldown.qdoc b/examples/sql/doc/src/drilldown.qdoc new file mode 100644 index 0000000000..9a7d0d003b --- /dev/null +++ b/examples/sql/doc/src/drilldown.qdoc @@ -0,0 +1,536 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example drilldown + \title Drill Down Example + + The Drill Down example shows how to read data from a database as + well as submit changes, using the QSqlRelationalTableModel and + QDataWidgetMapper classes. + + \image drilldown-example.png Screenshot of the Drill Down Example + + When running the example application, a user can retrieve + information about each of Nokia's Qt offices by clicking the + corresponding image. The application pops up an information window + displaying the data, and allows the users to alter the location + description as well as the image. The main view will be updated + when the users submit their changes. + + The example consists of three classes: + + \list + \li \c ImageItem is a custom graphics item class used to + display the office images. + + \li \c View is the main application widget allowing the user to + browse through the various locations. + + \li \c InformationWindow displays the requested information, + allowing the users to alter it and submit their changes to the + database. + \endlist + + We will first take a look at the \c InformationWindow class to see + how you can read and modify data from a database. Then we will + review the main application widget, i.e., the \c View class, and + the associated \c ImageItem class. + + \section1 InformationWindow Class Definition + + The \c InformationWindow class is a custom widget inheriting + QWidget: + + \snippet drilldown/informationwindow.h 0 + + When we create an information window, we pass the associated + location ID, a parent, and a pointer to the database, to the + constructor. We will use the database pointer to populate our + window with data, while passing the parent parameter on to the + base class. The ID is stored for future reference. + + Once a window is created, we will use the public \c id() function + to locate it whenever information for the given location is + requested. We will also use the ID to update the main application + widget when the users submit their changes to the database, i.e., + we will emit a signal carrying the ID and file name as parameters + whenever the users changes the associated image. + + \snippet drilldown/informationwindow.h 1 + + Since we allow the users to alter some of the location data, we + must provide functionality for reverting and submitting their + changes. The \c enableButtons() slot is provided for convenience + to enable and disable the various buttons when required. + + \snippet drilldown/informationwindow.h 2 + + The \c createButtons() function is also a convenience function, + provided to simplify the constructor. As mentioned above we store + the location ID for future reference. We also store the name of + the currently displayed image file to be able to determine when to + emit the \c imageChanged() signal. + + The information window uses the QLabel class to display the office + location and the country. The associated image file is displayed + using a QComboBox instance while the description is displayed using + QTextEdit. In addition, the window has three buttons to control + the data flow and whether the window is shown or not. + + Finally, we declare a \e mapper. The QDataWidgetMapper class + provides mapping between a section of a data model to widgets. We + will use the mapper to extract data from the given database, + updating the database whenever the user modifies the data. + + \section1 InformationWindow Class Implementation + + The constructor takes three arguments: a location ID, a database + pointer and a parent widget. The database pointer is actually a + pointer to a QSqlRelationalTableModel object providing an editable + data model (with foreign key support) for our database table. + + \snippet drilldown/informationwindow.cpp 0 + \snippet drilldown/informationwindow.cpp 1 + + First we create the various widgets required to display the data + contained in the database. Most of the widgets are created in a + straight forward manner. But note the combobox displaying the + name of the image file: + + \snippet drilldown/informationwindow.cpp 2 + + In this example, the information about the offices are stored in a + database table called "offices". When creating the model, + we will use a foreign key to establish a relation between this + table and a second data base table, "images", containing the names + of the available image files. We will get back to how this is done + when reviewing the \c View class. The rationale for creating such + a relation though, is that we want to ensure that the user only + can choose between predefined image files. + + The model corresponding to the "images" database table, is + available through the QSqlRelationalTableModel's \l + {QSqlRelationalTableModel::}{relationModel()} function, requiring + the foreign key (in this case the "imagefile" column number) as + argument. We use QComboBox's \l {QComboBox::}{setModel()} function + to make the combobox use the "images" model. And, since this model + has two columns ("locationid" and "file"), we also specify which + column we want to be visible using the QComboBox::setModelColumn() + function. + + \snippet drilldown/informationwindow.cpp 3 + + Then we create the mapper. The QDataWidgetMapper class allows us + to create data-aware widgets by mapping them to sections of an + item model. + + The \l {QDataWidgetMapper::}{addMapping()} function adds a mapping + between the given widget and the specified section of the + model. If the mapper's orientation is horizontal (the default) the + section is a column in the model, otherwise it is a row. We call + the \l {QDataWidgetMapper::}{setCurrentIndex()} function to + initialize the widgets with the data associated with the given + location ID. Every time the current index changes, all the widgets + are updated with the contents from the model. + + We also set the mapper's submit policy to + QDataWidgetMapper::ManualSubmit. This means that no data is + submitted to the database until the user expliclity requests a + submit (the alternative is QDataWidgetMapper::AutoSubmit, + automatically submitting changes when the corresponding widget + looses focus). Finally, we specify the item delegate the mapper + view should use for its items. The QSqlRelationalDelegate class + represents a delegate that unlike the default delegate, enables + combobox functionality for fields that are foreign keys into other + tables (like "imagefile" in our "trolltechoffices" table). + + \snippet drilldown/informationwindow.cpp 4 + + Finally, we connect the "something's changed" signals in the + editors to our custom \c enableButtons() slot, enabling the users + to either submit or revert their changes. We add all the widgets + into a layout, store the location ID and the name of the displayed + image file for future reference, and set the window title and + initial size. + + Note that we also set the Qt::Window window flag to indicate that + our widget is in fact a window, with a window system frame and a + title bar. + + \snippet drilldown/informationwindow.cpp 5 + + When a window is created, it is not deleted until the main + application exits (i.e., if the user closes the information + window, it is only hidden). For this reason we do not want to + create more than one \c InformationWindow object for each + location, and we provide the public \c id() function to be able to + determine whether a window already exists for a given location + when the user requests information about it. + + \snippet drilldown/informationwindow.cpp 6 + + The \c revert() slot is triggered whenever the user hits the \uicontrol + Revert button. + + Since we set the QDataWidgetMapper::ManualSubmit submit policy, + none of the user's changes are written back to the model unless + the user expliclity choose to submit all of them. Nevertheless, we + can use the QDataWidgetMapper's \l {QDataWidgetMapper::}{revert()} + slot to reset the editor widgets, repopulating all widgets with + the current data of the model. + + \snippet drilldown/informationwindow.cpp 7 + + Likewise, the \c submit() slot is triggered whenever the users + decide to submit their changes by pressing the \uicontrol Submit button. + + We use QDataWidgetMapper's \l {QDataWidgetMapper::}{submit()} slot + to submit all changes from the mapped widgets to the model, + i.e. to the database. For every mapped section, the item delegate + will then read the current value from the widget and set it in the + model. Finally, the \e model's \l {QAbstractItemModel::}{submit()} + function is invoked to let the model know that it should submit + whatever it has cached to the permanent storage. + + Note that before any data is submitted, we check if the user has + chosen another image file using the previously stored \c + displayedImage variable as reference. If the current and stored + file names differ, we store the new file name and emit the \c + imageChanged() signal. + + \snippet drilldown/informationwindow.cpp 8 + + The \c createButtons() function is provided for convenience, i.e., + to simplify the constructor. + + We make the \uicontrol Close button the default button, i.e., the button + that is pressed when the user presses \uicontrol Enter, and connect its + \l {QPushButton::}{clicked()} signal to the widget's \l + {QWidget::}{close()} slot. As mentioned above closing the window + only hides the widget; it is not deleted. We also connect the \uicontrol + Submit and \uicontrol Revert buttons to the corresponding \c submit() + and \c revert() slots. + + \snippet drilldown/informationwindow.cpp 9 + + The QDialogButtonBox class is a widget that presents buttons in a + layout that is appropriate to the current widget style. Dialogs + like our information window, typically present buttons in a layout + that conforms to the interface guidelines for that + platform. Invariably, different platforms have different layouts + for their dialogs. QDialogButtonBox allows us to add buttons, + automatically using the appropriate layout for the user's desktop + environment. + + Most buttons for a dialog follow certain roles. We give the \uicontrol + Submit and \uicontrol Revert buttons the \l + {QDialogButtonBox::ButtonRole}{reset} role, i.e., indicating that + pressing the button resets the fields to the default values (in + our case the information contained in the database). The \l + {QDialogButtonBox::ButtonRole}{reject} role indicates that + clicking the button causes the dialog to be rejected. On the other + hand, since we only hide the information window, any changes that + the user has made wil be preserved until the user expliclity + revert or submit them. + + \snippet drilldown/informationwindow.cpp 10 + + The \c enableButtons() slot is called to enable the buttons + whenever the user changes the presented data. Likewise, when the + data the user choose to submit the changes, the buttons are + disabled to indicate that the current data is stored in the + database. + + This completes the \c InformationWindow class. Let's take a look + at how we have used it in our example application. + + \section1 View Class Definition + + The \c View class represents the main application window and + inherits QGraphicsView: + + \snippet drilldown/view.h 0 + \codeline + \snippet drilldown/view.h 1 + + The QGraphicsView class is part of the \l {Graphics View + Framework} which we will use to display the images of Nokia's + Qt offices. To be able to respond to user interaction; + i.e., showing the + appropriate information window whenever the user clicks one of the + office images, we reimplement QGraphicsView's \l + {QGraphicsView::}{mouseReleaseEvent()} function. + + Note that the constructor expects the names of two database + tables: One containing the detailed information about the offices, + and another containing the names of the available image files. We + also provide a private \c updateImage() slot to catch \c + {InformationWindow}'s \c imageChanged() signal that is emitted + whenever the user changes a location's image. + + \snippet drilldown/view.h 2 + + The \c addItems() function is a convenience function provided to + simplify the constructor. It is called only once, creating the + various items and adding them to the view. + + The \c findWindow() function, on the other hand, is frequently + used. It is called from the \c showInformation() function to + detemine whether a window is already created for the given + location (whenever we create an \c InformationWindow object, we + store a reference to it in the \c informationWindows list). The + latter function is in turn called from our custom \c + mouseReleaseEvent() implementation. + + \snippet drilldown/view.h 3 + + Finally we declare a QSqlRelationalTableModel pointer. As + previously mentioned, the QSqlRelationalTableModel class provides + an editable data model with foreign key support. There are a + couple of things you should keep in mind when using the + QSqlRelationalTableModel class: The table must have a primary key + declared and this key cannot contain a relation to another table, + i.e., it cannot be a foreign key. Note also that if a relational + table contains keys that refer to non-existent rows in the + referenced table, the rows containing the invalid keys will not be + exposed through the model. It is the user's or the database's + responsibility to maintain referential integrity. + + \section1 View Class Implementation + + Although the constructor requests the names of both the table + containing office details as well as the table containing the + names of the available image files, we only have to create a + QSqlRelationalTableModel object for the office table: + + \snippet drilldown/view.cpp 0 + + The reason is that once we have a model with the office details, + we can create a relation to the available image files using + QSqlRelationalTableModel's \l + {QSqlRelationalTableModel::}{setRelation()} function. This + function creates a foreign key for the given model column. The key + is specified by the provided QSqlRelation object constructed by + the name of the table the key refers to, the field the key is + mapping to and the field that should be presented to the user. + + Note that setting the table only specifies which table the model + operates on, i.e., we must explicitly call the model's \l + {QSqlRelationalTableModel::}{select()} function to populate our + model. + + \snippet drilldown/view.cpp 1 + + Then we create the contents of our view, i.e., the scene and its + items. The location labels are regular QGraphicsTextItem objects, + and the "Qt" logo is represented by a QGraphicsPixmapItem + object. The images, on the other hand, are instances of the \c + ImageItem class (derived from QGraphicsPixmapItem). We will get + back to this shortly when reviewing the \c addItems() function. + + Finally, we set the main application widget's size constraints and + window title. + + \snippet drilldown/view.cpp 3 + + The \c addItems() function is called only once, i.e., when + creating the main application window. For each row in the database + table, we first extract the corresponding record using the model's + \l {QSqlRelationalTableModel::}{record()} function. The QSqlRecord + class encapsulates both the functionality and characteristics of a + database record, and supports adding and removing fields as well + as setting and retrieving field values. The QSqlRecord::value() + function returns the value of the field with the given name or + index as a QVariant object. + + For each record, we create a label item as well as an image item, + calculate their position and add them to the scene. The image + items are represented by instances of the \c ImageItem class. The + reason we must create a custom item class is that we want to catch + the item's hover events, animating the item when the mouse cursor + is hovering over the image (by default, no items accept hover + events). Please see the \l{Graphics View Framework} documentation + and the \l{Graphics View Examples} for more details. + + \snippet drilldown/view.cpp 5 + + We reimplement QGraphicsView's \l + {QGraphicsView::}{mouseReleaseEvent()} event handler to respond to + user interaction. If the user clicks any of the image items, this + function calls the private \c showInformation() function to pop up + the associated information window. + + The \l {Graphics View Framework} provides the qgraphicsitem_cast() + function to determine whether the given QGraphicsItem instance is + of a given type. Note that if the event is not related to any of + our image items, we pass it on to the base class implementation. + + \snippet drilldown/view.cpp 6 + + The \c showInformation() function is given an \c ImageItem object + as argument, and starts off by extracting the item's location + ID. Then it determines if there already is created an information + window for this location. If it is, and the window is visible, it + ensures that the window is raised to the top of the widget stack + and activated. If the window exists but is hidden, calling its \l + {QWidget::}{show()} slot gives the same result. + + If no window for the given location exists, we create one by + passing the location ID, a pointer to the model, and our view as a + parent, to the \c InformationWindow constructor. Note that we + connect the information window's \c imageChanged() signal to \e + this widget's \c updateImage() slot, before we give it a suitable + position and add it to the list of existing windows. + + \snippet drilldown/view.cpp 7 + + The \c updateImage() slot takes a location ID and the name of an + image files as arguments. It filters out the image items, and + updates the one that correspond to the given location ID, with the + provided image file. + + \snippet drilldown/view.cpp 8 + + The \c findWindow() function simply searches through the list of + existing windows, returning a pointer to the window that matches + the given location ID, or 0 if the window doesn't exists. + + Finally, let's take a quick look at our custom \c ImageItem class: + + \section1 ImageItem Class Definition + + The \c ImageItem class is provided to facilitate animation of the + image items. It inherits QGraphicsPixmapItem and reimplements its + hover event handlers: + + \snippet drilldown/imageitem.h 0 + + In addition, we implement a public \c id() function to be able to + identify the associated location and a public \c adjust() function + that can be called to ensure that the image item is given the + preferred size regardless of the original image file. + + The animation is implemented using the QTimeLine class together + with the event handlers and the private \c setFrame() slot: The + image item will expand when the mouse cursor hovers over it, + returning back to its original size when the cursor leaves its + borders. + + Finally, we store the location ID that this particular record is + associated with as well as a z-value. In the \l {Graphics View + Framework}, an item's z-value determines its position in the item + stack. An item of high z-value will be drawn on top of an item + with a lower z-value if they share the same parent item. We also + provide an \c updateItemPosition() function to refresh the view + when required. + + \section1 ImageItem Class Implementation + + The \c ImageItem class is really only a QGraphicsPixmapItem with + some additional features, i.e., we can pass most of the + constructor's arguments (the pixmap, parent and scene) on to the + base class constructor: + + \snippet drilldown/imageitem.cpp 0 + + Then we store the ID for future reference, and ensure that our + item will accept hover events. Hover events are delivered when + there is no current mouse grabber item. They are sent when the + mouse cursor enters an item, when it moves around inside the item, + and when the cursor leaves an item. As we mentioned earlier, none + of the \l {Graphics View Framework}'s items accept hover + event's by default. + + The QTimeLine class provides a timeline for controlling + animations. Its \l {QTimeLine::}{duration} property holds the + total duration of the timeline in milliseconds. By default, the + time line runs once from the beginning and towards the end. The + QTimeLine::setFrameRange() function sets the timeline's frame + counter; when the timeline is running, the \l + {QTimeLine::}{frameChanged()} signal is emitted each time the + frame changes. We set the duration and frame range for our + animation, and connect the time line's \l + {QTimeLine::}{frameChanged()} and \l {QTimeLine::}{finished()} + signals to our private \c setFrame() and \c updateItemPosition() + slots. + + Finally, we call \c adjust() to ensure that the item is given the + preferred size. + + \snippet drilldown/imageitem.cpp 1 + \codeline + \snippet drilldown/imageitem.cpp 2 + + Whenever the mouse cursor enters or leave the image item, the + corresponding event handlers are triggered: We first set the time + line's direction, making the item expand or shrink, + respectively. Then we alter the item's z-value if it is not already + set to the expected value. + + In the case of hover \e enter events, we immediately update the + item's position since we want the item to appear on top of all + other items as soon as it starts expanding. In the case of hover + \e leave events, on the other hand, we postpone the actual update + to achieve the same result. But remember that when we constructed + our item, we connected the time line's \l + {QTimeLine::}{finished()} signal to the \c updateItemPosition() + slot. In this way the item is given the correct position in the + item stack once the animation is completed. Finally, if the time + line is not already running, we start it. + + \snippet drilldown/imageitem.cpp 3 + + When the time line is running, it triggers the \c setFrame() slot + whenever the current frame changes due to the connection we + created in the item constructor. It is this slot that controls the + animation, expanding or shrinking the image item step by step. + + We first call the \c adjust() function to ensure that we start off + with the item's original size. Then we scale the item with a + factor depending on the animation's progress (using the \c frame + parameter). Note that by default, the transformation will be + relative to the item's top-left corner. Since we want the item to + be transformed relative to its center, we must translate the + coordinate system before we scale the item. + + In the end, only the following convenience functions remain: + + \snippet drilldown/imageitem.cpp 4 + \codeline + \snippet drilldown/imageitem.cpp 5 + \codeline + \snippet drilldown/imageitem.cpp 6 + + The \c adjust() function defines and applies a transformation + matrix, ensuring that our image item appears with the preferred + size regardless of the size of the source image. The \c id() + function is trivial, and is simply provided to be able to identify + the item. In the \c updateItemPosition() slot we call the + QGraphicsItem::setZValue() function, setting the elevation (i.e., + the position) of the item. +*/ diff --git a/examples/sql/doc/src/masterdetail.qdoc b/examples/sql/doc/src/masterdetail.qdoc new file mode 100644 index 0000000000..c8ec68f639 --- /dev/null +++ b/examples/sql/doc/src/masterdetail.qdoc @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example masterdetail + \title Master Detail Example + + The Master Detail Example shows how to present data from different + data sources in the same application. The album titles, and the + corresponding artists and release dates, are kept in a + database, while each album's tracks are stored in an XML + file. + + The example also shows how to add as well as remove data from both + the database and the associated XML file using the API provided by + the QtSql and QtXml modules, respectively. + + \image masterdetail-example.png +*/ diff --git a/examples/sql/doc/src/querymodel.qdoc b/examples/sql/doc/src/querymodel.qdoc new file mode 100644 index 0000000000..2d1f3c90b1 --- /dev/null +++ b/examples/sql/doc/src/querymodel.qdoc @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example querymodel + \title Query Model Example + + The Query Model example shows how to make customized versions of + data obtained from a SQL query, using a model that encapsulates + the query and table views to display the results. + + \image querymodel-example.png +*/ diff --git a/examples/sql/doc/src/relationaltablemodel.qdoc b/examples/sql/doc/src/relationaltablemodel.qdoc new file mode 100644 index 0000000000..619554ff91 --- /dev/null +++ b/examples/sql/doc/src/relationaltablemodel.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example relationaltablemodel + \title Relational Table Model Example + + The Relational Table Model example shows how to use table views with a relational + model to visualize the relations between items in a database. + + \image relationaltablemodel-example.png +*/ diff --git a/examples/sql/doc/src/sqlbrowser.qdoc b/examples/sql/doc/src/sqlbrowser.qdoc new file mode 100644 index 0000000000..302964cf75 --- /dev/null +++ b/examples/sql/doc/src/sqlbrowser.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sqlbrowser + \title SQL Browser + + The SQL Browser example shows how a data browser can be used to visualize + the results of SQL statements on a live database. + + \image sqlbrowser-demo.png +*/ diff --git a/examples/sql/doc/src/sqlwidgetmapper.qdoc b/examples/sql/doc/src/sqlwidgetmapper.qdoc new file mode 100644 index 0000000000..cc1c51c97f --- /dev/null +++ b/examples/sql/doc/src/sqlwidgetmapper.qdoc @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example sqlwidgetmapper + \title SQL Widget Mapper Example + + The SQL Widget Mapper example shows how to use a map information from a + database to widgets on a form. + + \image sql-widget-mapper.png + + In the \l{Combo Widget Mapper Example}, we showed how to use a named + mapping between a widget mapper and a QComboBox widget with a special + purpose model to relate values in the model to a list of choices. + + Again, we create a \c Window class with an almost identical user interface, + providing a combo box to allow their addresses to be classified as "Home", + "Work" or "Other". However, instead of using a separate model to hold these + address types, we use one database table to hold the example data and + another to hold the address types. In this way, we store all the + information in the same place. + + \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 sqlwidgetmapper/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 first act performed by the \c Window class constructor is to set up + the model used to hold the example data. Since this is a key part of the + example, we will look at this first. + + The model is initialized in the window's \c{setupModel()} function. Here, + we create a SQLite database containing a "person" table with primary key, + name, address and type fields. + + \snippet sqlwidgetmapper/window.cpp Set up the main table + + On each row of the table, we insert default values for these fields, + including values for the address types that correspond to the address + types are stored in a separate table. + + \image widgetmapper-sql-mapping-table.png + + We create an "addresstype" table containing the identifiers used in the + "person" table and the corresponding strings: + + \snippet sqlwidgetmapper/window.cpp Set up the address type table + + The "typeid" field in the "person" table is related to the contents of + the "addresstype" table via a relation in a QSqlRelationalTableModel. + This kind of model performs all the necessary work to store the data in + a database and also allows any relations to be used as models in their + own right. + + In this case, we have defined a relation for the "typeid" field in the + "person" table that relates it to the "id" field in the "addresstype" + table and which causes the contents of the "description" field to be + used wherever the "typeid" is presented to the user. (See the + QSqlRelationalTableModel::setRelation() documentation for details.) + + \image widgetmapper-sql-mapping.png + + The constructor of the \c Window class can be explained in three parts. + In the first part, we set up the model used to hold the data, then we set + up the widgets used for the user interface: + + \snippet sqlwidgetmapper/window.cpp Set up widgets + + We obtain a model for the combo box from the main model, based on the + relation we set up for the "typeid" field. The call to the combo box's + \l{QComboBox::}{setModelColumn()} selects the field in the field in the + model to display. + + Note that this approach is similar to the one used in the + \l{Combo Widget Mapper Example} in that we set up a model for the + combo box. However, in this case, we obtain a model based on a relation + in the QSqlRelationalTableModel rather than create a separate one. + + Next, we set up the widget mapper, relating each input widget to a field + in the model: + + \snippet sqlwidgetmapper/window.cpp Set up the mapper + + For the combo box, we already know the index of the field in the model + from the \c{setupModel()} function. We use a QSqlRelationalDelegate as + a proxy between the mapper and the input widgets to match up the "typeid" + values in the model with those in the combo box's model and populate the + combo box with descriptions rather than integer values. + + As a result, the user is able to select an item from the combo box, + and the associated value is written back to the model. + + The rest of the constructor is very similar to that of the + \l{Simple Widget Mapper Example}: + + \snippet sqlwidgetmapper/window.cpp Set up connections and layouts + + We show the implementation of the \c{updateButtons()} slot for + completeness: + + \snippet sqlwidgetmapper/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 sqlwidgetmapper/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 sqlwidgetmapper/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 sqlwidgetmapper/delegate.cpp setModelData implementation + \endomit + + \section1 Summary and Further Reading + + The use of a separate model for the combo box and a special delegate for the + widget mapper allows us to present a menu of choices to the user. Although + the choices are stored in the same database as the user's data, they are held + in a separate table. Using this approach, we can reconstructed complete records + at a later time while using database features appropriately. + + If SQL models are not being used, it is still possible to use more than + one model to present choices to the user. This is covered by the + \l{Combo Widget Mapper Example}. +*/ diff --git a/examples/sql/doc/src/tablemodel.qdoc b/examples/sql/doc/src/tablemodel.qdoc new file mode 100644 index 0000000000..1a08048dd9 --- /dev/null +++ b/examples/sql/doc/src/tablemodel.qdoc @@ -0,0 +1,36 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example tablemodel + \title Table Model Example + + The Table Model example shows how to use a specialized SQL table model with table + views to edit information in a database. + + \image tablemodel-example.png +*/ |