|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 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/cachedtable |
|
44 \title Cached Table Example |
|
45 |
|
46 The Cached Table example shows how a table view can be used to access a database, |
|
47 caching any changes to the data until the user explicitly submits them using a |
|
48 push button. |
|
49 |
|
50 \image cachedtable-example.png |
|
51 |
|
52 The example consists of a single class, \c TableEditor, which is a |
|
53 custom dialog widget that allows the user to modify data stored in |
|
54 a database. We will first review the class definiton and how to |
|
55 use the class, then we will take a look at the implementation. |
|
56 |
|
57 \section1 TableEditor Class Definition |
|
58 |
|
59 The \c TableEditor class inherits QDialog making the table editor |
|
60 widget a top-level dialog window. |
|
61 |
|
62 \snippet examples/sql/cachedtable/tableeditor.h 0 |
|
63 |
|
64 The \c TableEditor constructor takes two arguments: The first is a |
|
65 pointer to the parent widget and is passed on to the base class |
|
66 constructor. The other is a reference to the database table the \c |
|
67 TableEditor object will operate on. |
|
68 |
|
69 Note the QSqlTableModel variable declaration: As we will see in |
|
70 this example, the QSqlTableModel class can be used to provide data |
|
71 to view classes such as QTableView. The QSqlTableModel class |
|
72 provides an editable data model making it possible to read and |
|
73 write database records from a single table. It is build on top of |
|
74 the lower-level QSqlQuery class which provides means of executing |
|
75 and manipulating SQL statements. |
|
76 |
|
77 We are also going to show how a table view can be used to cache |
|
78 any changes to the data until the user explicitly requests to |
|
79 submit them. For that reason we need to declare a \c submit() slot |
|
80 in additon to the model and the editor's buttons. |
|
81 |
|
82 \table 100% |
|
83 \header \o Connecting to a Database |
|
84 \row |
|
85 \o |
|
86 |
|
87 Before we can use the \c TableEditor class, we must create a |
|
88 connection to the database containing the table we want to edit: |
|
89 |
|
90 \snippet examples/sql/cachedtable/main.cpp 0 |
|
91 |
|
92 The \c createConnection() function is a helper function provided |
|
93 for convenience. It is defined in the \c connection.h file which |
|
94 is located in the \c sql example directory (all the examples in |
|
95 the \c sql directory use this function to connect to a database). |
|
96 |
|
97 \snippet examples/sql/connection.h 0 |
|
98 |
|
99 The \c createConnection function opens a connection to an |
|
100 in-memory SQLITE database and creates a test table. If you want |
|
101 to use another database, simply modify this function's code. |
|
102 \endtable |
|
103 |
|
104 \section1 TableEditor Class Implementation |
|
105 |
|
106 The class implementation consists of only two functions, the |
|
107 constructor and the \c submit() slot. In the constructor we create |
|
108 and customize the data model and the various window elements: |
|
109 |
|
110 \snippet examples/sql/cachedtable/tableeditor.cpp 0 |
|
111 |
|
112 First we create the data model and set the SQL database table we |
|
113 want the model to operate on. Note that the |
|
114 QSqlTableModel::setTable() function does not select data from the |
|
115 table; it only fetches its field information. For that reason we |
|
116 call the QSqlTableModel::select() function later on, populating |
|
117 the model with data from the table. The selection can be |
|
118 customized by specifying filters and sort conditions (see the |
|
119 QSqlTableModel class documentation for more details). |
|
120 |
|
121 We also set the model's edit strategy. The edit strategy dictates |
|
122 when the changes done by the user in the view, are actually |
|
123 applied to the database. Since we want to cache the changes in the |
|
124 table view (i.e. in the model) until the user explicitly submits |
|
125 them, we choose the QSqlTableModel::OnManualSubmit strategy. The |
|
126 alternatives are QSqlTableModel::OnFieldChange and |
|
127 QSqlTableModel::OnRowChange. |
|
128 |
|
129 Finally, we set up the labels displayed in the view header using |
|
130 the \l {QSqlQueryModel::setHeaderData()}{setHeaderData()} function |
|
131 that the model inherits from the QSqlQueryModel class. |
|
132 |
|
133 \snippet examples/sql/cachedtable/tableeditor.cpp 1 |
|
134 |
|
135 Then we create a table view. The QTableView class provides a |
|
136 default model/view implementation of a table view, i.e. it |
|
137 implements a table view that displays items from a model. It also |
|
138 allows the user to edit the items, storing the changes in the |
|
139 model. To create a read only view, set the proper flag using the |
|
140 \l {QAbstractItemView::editTriggers}{editTriggers} property the |
|
141 view inherits from the QAbstractItemView class. |
|
142 |
|
143 To make the view present our data, we pass our model to the view |
|
144 using the \l {QAbstractItemView::setModel()}{setModel()} function. |
|
145 |
|
146 \snippet examples/sql/cachedtable/tableeditor.cpp 2 |
|
147 |
|
148 The \c {TableEditor}'s buttons are regular QPushButton objects. We |
|
149 add them to a button box to ensure that the buttons are presented |
|
150 in a layout that is appropriate to the current widget style. The |
|
151 rationale for this is that dialogs and message boxes typically |
|
152 present buttons in a layout that conforms to the interface |
|
153 guidelines for that platform. Invariably, different platforms have |
|
154 different layouts for their dialogs. QDialogButtonBox allows a |
|
155 developer to add buttons to it and will automatically use the |
|
156 appropriate layout for the user's desktop environment. |
|
157 |
|
158 Most buttons for a dialog follow certain roles. When adding a |
|
159 button to a button box using the \l |
|
160 {QDialogButtonBox}{addButton()} function, the button's role must |
|
161 be specified using the QDialogButtonBox::ButtonRole |
|
162 enum. Alternatively, QDialogButtonBox provides several standard |
|
163 buttons (e.g. \gui OK, \gui Cancel, \gui Save) that you can |
|
164 use. They exist as flags so you can OR them together in the |
|
165 constructor. |
|
166 |
|
167 \snippet examples/sql/cachedtable/tableeditor.cpp 3 |
|
168 |
|
169 We connect the \gui Quit button to the table editor's \l |
|
170 {QWidget::close()}{close()} slot, and the \gui Submit button to |
|
171 our private \c submit() slot. The latter slot will take care of |
|
172 the data transactions. Finally, we connect the \gui Revert button |
|
173 to our model's \l {QSqlTableModel::revertAll()}{revertAll()} slot, |
|
174 reverting all pending changes (i.e., restoring the original data). |
|
175 |
|
176 \snippet examples/sql/cachedtable/tableeditor.cpp 4 |
|
177 |
|
178 In the end we add the button box and the table view to a layout, |
|
179 install the layout on the table editor widget, and set the |
|
180 editor's window title. |
|
181 |
|
182 \snippet examples/sql/cachedtable/tableeditor.cpp 5 |
|
183 |
|
184 The \c submit() slot is called whenever the users hit the \gui |
|
185 Submit button to save their changes. |
|
186 |
|
187 First, we begin a transaction on the database using the |
|
188 QSqlDatabase::transaction() function. A database transaction is a |
|
189 unit of interaction with a database management system or similar |
|
190 system that is treated in a coherent and reliable way independent |
|
191 of other transactions. A pointer to the used database can be |
|
192 obtained using the QSqlTableModel::database() function. |
|
193 |
|
194 Then, we try to submit all the pending changes, i.e. the model's |
|
195 modified items. If no error occurs, we commit the transaction to |
|
196 the database using the QSqlDatabase::commit() function (note that |
|
197 on some databases, this function will not work if there is an |
|
198 active QSqlQuery on the database). Otherwise we perform a rollback |
|
199 of the transaction using the QSqlDatabase::rollback() function and |
|
200 post a warning to the user. |
|
201 |
|
202 \table 100% |
|
203 \row |
|
204 \o |
|
205 \bold {See also:} |
|
206 |
|
207 A complete list of Qt's SQL \l {Database Classes}, and the \l |
|
208 {Model/View Programming} documentation. |
|
209 |
|
210 \endtable |
|
211 */ |