0
|
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 |
\group database
|
|
44 |
\title Database Classes
|
|
45 |
|
|
46 |
\brief Database related classes, e.g. for SQL databases.
|
|
47 |
*/
|
|
48 |
|
|
49 |
/*!
|
|
50 |
\page sql-programming.html
|
|
51 |
\title SQL Programming
|
|
52 |
|
|
53 |
\brief Database integration for Qt applications.
|
|
54 |
|
|
55 |
This overview assumes that you have at least a basic knowledge of
|
|
56 |
SQL. You should be able to understand simple \c SELECT, \c
|
|
57 |
INSERT, \c UPDATE, and \c DELETE statements. Although the \l
|
|
58 |
QSqlTableModel class provides an interface to database browsing
|
|
59 |
and editing that does not require a knowledge of SQL, a basic
|
|
60 |
understanding of SQL is highly recommended. A standard text
|
|
61 |
covering SQL databases is \e {An Introduction to Database Systems}
|
|
62 |
(7th Ed.) by C. J. Date, ISBN 0201385902.
|
|
63 |
|
|
64 |
\section1 Topics:
|
|
65 |
|
|
66 |
\list
|
|
67 |
\o \l{Database Classes}
|
|
68 |
\o \l{Connecting to Databases}
|
|
69 |
\list
|
|
70 |
\o \l{SQL Database Drivers}
|
|
71 |
\endlist
|
|
72 |
\o \l{Executing SQL Statements}
|
|
73 |
\list
|
|
74 |
\o \l{Recommended Use of Data Types in Databases}
|
|
75 |
\endlist
|
|
76 |
\o \l{Using the SQL Model Classes}
|
|
77 |
\o \l{Presenting Data in a Table View}
|
|
78 |
\o \l{Creating Data-Aware Forms}
|
|
79 |
\endlist
|
|
80 |
|
|
81 |
\section1 Database Classes
|
|
82 |
|
|
83 |
These classes provide access to SQL databases.
|
|
84 |
|
|
85 |
\annotatedlist database
|
|
86 |
|
|
87 |
The SQL classes are divided into three layers:
|
|
88 |
|
|
89 |
\section2 Driver Layer
|
|
90 |
|
|
91 |
This comprises the classes QSqlDriver, QSqlDriverCreator<T>,
|
|
92 |
QSqlDriverCreatorBase, QSqlDriverPlugin, and QSqlResult.
|
|
93 |
|
|
94 |
This layer provides the low-level bridge between the specific databases
|
|
95 |
and the SQL API layer. See \l{SQL Database Drivers} for more information.
|
|
96 |
|
|
97 |
\section2 SQL API Layer
|
|
98 |
|
|
99 |
These classes provide access to databases. Connections
|
|
100 |
are made using the QSqlDatabase class. Database
|
|
101 |
interaction is achieved by using the QSqlQuery class.
|
|
102 |
In addition to QSqlDatabase and QSqlQuery, the SQL API
|
|
103 |
layer is supported by QSqlError, QSqlField, QSqlIndex,
|
|
104 |
and QSqlRecord.
|
|
105 |
|
|
106 |
\section2 User Interface Layer
|
|
107 |
|
|
108 |
These classes link the data from a database to data-aware widgets.
|
|
109 |
They include QSqlQueryModel, QSqlTableModel, and QSqlRelationalTableModel.
|
|
110 |
These classes are designed to work with Qt's
|
|
111 |
\l{Model/View Programming}{model/view framework}.
|
|
112 |
|
|
113 |
Note that to use any of these classes, a QCoreApplication object
|
|
114 |
must have been instantiated first.
|
|
115 |
*/
|
|
116 |
|
|
117 |
/*!
|
|
118 |
\page sql-connecting.html
|
|
119 |
\title Connecting to Databases
|
|
120 |
|
|
121 |
\contentspage SQL Programming
|
|
122 |
\nextpage Executing SQL Statements
|
|
123 |
|
|
124 |
To access a database with QSqlQuery or QSqlQueryModel, create and
|
|
125 |
open one or more database connections. Database connections are
|
|
126 |
normally identified by connection name, \e{not} by database name.
|
|
127 |
You can have multiple connections to the same database.
|
|
128 |
QSqlDatabase also supports the concept of a \e{default}
|
|
129 |
connection, which is an unnamed connection. When calling QSqlQuery
|
|
130 |
or QSqlQueryModel member functions that take a connection name
|
|
131 |
argument, if you don't pass a connection name, the default
|
|
132 |
connection will be used. Creating a default connection is
|
|
133 |
convenient when your application only requires one database
|
|
134 |
connection.
|
|
135 |
|
|
136 |
Note the difference between creating a connection and opening it.
|
|
137 |
Creating a connection involves creating an instance of class
|
|
138 |
QSqlDatabase. The connection is not usable until it is opened. The
|
|
139 |
following snippet shows how to create a \e{default} connection
|
|
140 |
and then open it:
|
|
141 |
|
|
142 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 26
|
|
143 |
|
|
144 |
The first line creates the connection object, and the last line
|
|
145 |
opens it for use. In between, we initialize some connection
|
|
146 |
information, including the \l{QSqlDatabase::setDatabaseName()}
|
|
147 |
{database name}, the \l{QSqlDatabase::setHostName()} {host name},
|
|
148 |
the \l{QSqlDatabase::setUserName()} {user name}, and the
|
|
149 |
\l{QSqlDatabase::setPassword()} {password}. In this case, we are
|
|
150 |
connecting to the MySQL database \c{flightdb} on the host
|
|
151 |
\c{bigblue}. The \c{"QMYSQL"} argument to
|
|
152 |
\l{QSqlDatabase::addDatabase()} {addDatabase()} specifies the type
|
|
153 |
of database driver to use for the connection. The set of database
|
|
154 |
drivers included with Qt are shown in the table of \l{SQL Database
|
|
155 |
Drivers#Supported Databases} {supported database drivers}.
|
|
156 |
|
|
157 |
The connection in the snippet will be the \e{default} connection,
|
|
158 |
because we don't pass the second argument to
|
|
159 |
\l{QSqlDatabase::addDatabase()} {addDatabase()}, which is the
|
|
160 |
connection name. For example, here we establish two MySQL database
|
|
161 |
connections named \c{"first"} and \c{"second"}:
|
|
162 |
|
|
163 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 27
|
|
164 |
|
|
165 |
After these connections have been initialized, \l{QSqlDatabase::}
|
|
166 |
{open()} for each one to establish the live connections. If the
|
|
167 |
\l{QSqlDatabase::} {open()} fails, it returns false. In that case,
|
|
168 |
call QSqlDatabase::lastError() to get error information.
|
|
169 |
|
|
170 |
Once a connection is established, we can call the static function
|
|
171 |
QSqlDatabase::database() from anywhere with a connection name to
|
|
172 |
get a pointer to that database connection. If we don't pass a
|
|
173 |
connection name, it will return the default connection. For
|
|
174 |
example:
|
|
175 |
|
|
176 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 28
|
|
177 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 29
|
|
178 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 30
|
|
179 |
|
|
180 |
To remove a database connection, first close the database using
|
|
181 |
QSqlDatabase::close(), then remove it using the static method
|
|
182 |
QSqlDatabase::removeDatabase().
|
|
183 |
*/
|
|
184 |
|
|
185 |
/*!
|
|
186 |
\page sql-sqlstatements.html
|
|
187 |
\title Executing SQL Statements
|
|
188 |
|
|
189 |
\previouspage Connecting to Databases
|
|
190 |
\contentspage SQL Programming
|
|
191 |
\nextpage Using the SQL Model Classes
|
|
192 |
|
|
193 |
|
|
194 |
The QSqlQuery class provides an interface for executing SQL
|
|
195 |
statements and navigating through the result set of a query.
|
|
196 |
|
|
197 |
The QSqlQueryModel and QSqlTableModel classes described in the
|
|
198 |
next section provide a higher-level interface for accessing
|
|
199 |
databases. If you are unfamiliar with SQL, you might want to skip
|
|
200 |
directly to the next section (\l{Using the SQL Model Classes}).
|
|
201 |
|
|
202 |
\section2 Executing a Query
|
|
203 |
|
|
204 |
To execute an SQL statement, simply create a QSqlQuery object and
|
|
205 |
call QSqlQuery::exec() like this:
|
|
206 |
|
|
207 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 31
|
|
208 |
|
|
209 |
The QSqlQuery constructor accepts an optional QSqlDatabase object
|
|
210 |
that specifies which database connection to use. In the example
|
|
211 |
above, we don't specify any connection, so the default connection
|
|
212 |
is used.
|
|
213 |
|
|
214 |
If an error occurs, \l{QSqlQuery::exec()}{exec()} returns false.
|
|
215 |
The error is then available as QSqlQuery::lastError().
|
|
216 |
|
|
217 |
\section2 Navigating the Result Set
|
|
218 |
|
|
219 |
QSqlQuery provides access to the result set one record at a time.
|
|
220 |
After the call to \l{QSqlQuery::exec()}{exec()}, QSqlQuery's
|
|
221 |
internal pointer is located one position \e{before} the first
|
|
222 |
record. We must call QSqlQuery::next() once to advance to the
|
|
223 |
first record, then \l{QSqlQuery::next()}{next()} again repeatedly
|
|
224 |
to access the other records, until it returns false. Here's a
|
|
225 |
typical loop that iterates over all the records in order:
|
|
226 |
|
|
227 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 32
|
|
228 |
|
|
229 |
The QSqlQuery::value() function returns the value of a field in
|
|
230 |
the current record. Fields are specified as zero-based indexes.
|
|
231 |
QSqlQuery::value() returns a QVariant, a type that can hold
|
|
232 |
various C++ and core Qt data types such as \c int, QString, and
|
|
233 |
QByteArray. The different database types are automatically mapped
|
|
234 |
into the closest Qt equivalent. In the code snippet, we call
|
|
235 |
QVariant::toString() and QVariant::toInt() to convert
|
|
236 |
variants to QString and \c int.
|
|
237 |
|
|
238 |
For an overview of the recommended types used with Qt supported
|
|
239 |
Databases, please refer to \l{Recommended Use of Data Types in Databases}{this table}.
|
|
240 |
|
|
241 |
You can iterate back and forth using QSqlQuery::next(),
|
|
242 |
QSqlQuery::previous(), QSqlQuery::first(), QSqlQuery::last(), and
|
|
243 |
QSqlQuery::seek(). The current row index is returned by
|
|
244 |
QSqlQuery::at(), and the total number of rows in the result set
|
|
245 |
is avaliable as QSqlQuery::size() for databases that support it.
|
|
246 |
|
|
247 |
To determine whether a database driver supports a given feature,
|
|
248 |
use QSqlDriver::hasFeature(). In the following example, we call
|
|
249 |
QSqlQuery::size() to determine the size of a result set of
|
|
250 |
the underlying database supports that feature; otherwise, we
|
|
251 |
navigate to the last record and use the query's position to tell
|
|
252 |
us how many records there are.
|
|
253 |
|
|
254 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 33
|
|
255 |
|
|
256 |
If you iterate through a result set only using next() and seek()
|
|
257 |
with positive values, you can call
|
|
258 |
QSqlQuery::setForwardOnly(true) before calling exec(). This is an
|
|
259 |
easy optimization that will speed up the query significantly when
|
|
260 |
operating on large result sets.
|
|
261 |
|
|
262 |
\section2 Inserting, Updating, and Deleting Records
|
|
263 |
|
|
264 |
QSqlQuery can execute arbitrary SQL statements, not just
|
|
265 |
\c{SELECT}s. The following example inserts a record into a table
|
|
266 |
using \c{INSERT}:
|
|
267 |
|
|
268 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 34
|
|
269 |
|
|
270 |
If you want to insert many records at the same time, it is often
|
|
271 |
more efficient to separate the query from the actual values being
|
|
272 |
inserted. This can be done using placeholders. Qt supports two
|
|
273 |
placeholder syntaxes: named binding and positional binding.
|
|
274 |
Here's an example of named binding:
|
|
275 |
|
|
276 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 35
|
|
277 |
|
|
278 |
Here's an example of positional binding:
|
|
279 |
|
|
280 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 36
|
|
281 |
|
|
282 |
Both syntaxes work with all database drivers provided by Qt. If
|
|
283 |
the database supports the syntax natively, Qt simply forwards the
|
|
284 |
query to the DBMS; otherwise, Qt simulates the placeholder syntax
|
|
285 |
by preprocessing the query. The actual query that ends up being
|
|
286 |
executed by the DBMS is available as QSqlQuery::executedQuery().
|
|
287 |
|
|
288 |
When inserting multiple records, you only need to call
|
|
289 |
QSqlQuery::prepare() once. Then you call
|
|
290 |
\l{QSqlQuery::bindValue()}{bindValue()} or
|
|
291 |
\l{QSqlQuery::addBindValue()}{addBindValue()} followed by
|
|
292 |
\l{QSqlQuery::exec()}{exec()} as many times as necessary.
|
|
293 |
|
|
294 |
Besides performance, one advantage of placeholders is that you
|
|
295 |
can easily specify arbitrary values without having to worry about
|
|
296 |
escaping special characters.
|
|
297 |
|
|
298 |
Updating a record is similar to inserting it into a table:
|
|
299 |
|
|
300 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 37
|
|
301 |
|
|
302 |
You can also use named or positional binding to associate
|
|
303 |
parameters to actual values.
|
|
304 |
|
|
305 |
Finally, here's an example of a \c DELETE statement:
|
|
306 |
|
|
307 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 38
|
|
308 |
|
|
309 |
\section2 Transactions
|
|
310 |
|
|
311 |
If the underlying database engine supports transactions,
|
|
312 |
QSqlDriver::hasFeature(QSqlDriver::Transactions) will return
|
|
313 |
true. You can use QSqlDatabase::transaction() to initiate a
|
|
314 |
transaction, followed by the SQL commands you want to execute
|
|
315 |
within the context of the transaction, and then either
|
|
316 |
QSqlDatabase::commit() or QSqlDatabase::rollback(). When
|
|
317 |
using transactions you must start the transaction before you
|
|
318 |
create your query.
|
|
319 |
|
|
320 |
Example:
|
|
321 |
|
|
322 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 39
|
|
323 |
|
|
324 |
Transactions can be used to ensure that a complex operation is
|
|
325 |
atomic (for example, looking up a foreign key and creating a
|
|
326 |
record), or to provide a means of canceling a complex change in
|
|
327 |
the middle.
|
|
328 |
|
|
329 |
\omit
|
|
330 |
It would be useful to mention transactions, and the fact that
|
|
331 |
some databases don't support them.
|
|
332 |
\endomit
|
|
333 |
*/
|
|
334 |
|
|
335 |
/*!
|
|
336 |
\page sql-model.html
|
|
337 |
\title Using the SQL Model Classes
|
|
338 |
|
|
339 |
\previouspage Executing SQL Statements
|
|
340 |
\contentspage SQL Programming
|
|
341 |
\nextpage Presenting Data in a Table View
|
|
342 |
|
|
343 |
In addition to QSqlQuery, Qt offers three higher-level classes
|
|
344 |
for accessing databases. These classes are QSqlQueryModel,
|
|
345 |
QSqlTableModel, and QSqlRelationalTableModel.
|
|
346 |
|
|
347 |
\table
|
|
348 |
\row \o QSqlQueryModel
|
|
349 |
\o A read-only model based on an arbitrary SQL query.
|
|
350 |
\row \o QSqlTableModel
|
|
351 |
\o A read-write model that works on a single table.
|
|
352 |
\row \o QSqlRelationalTableModel
|
|
353 |
\o A QSqlTableModel subclass with foreign key support.
|
|
354 |
\endtable
|
|
355 |
|
|
356 |
These classes derive from QAbstractTableModel (which in turn
|
|
357 |
inherits from QAbstractItemModel) and make it easy to present
|
|
358 |
data from a database in an item view class such as QListView and
|
|
359 |
QTableView. This is explained in detail in the \l{Presenting Data
|
|
360 |
in a Table View} section.
|
|
361 |
|
|
362 |
Another advantage of using these classes is that it can make your
|
|
363 |
code easier to adapt to other data sources. For example, if you
|
|
364 |
use QSqlTableModel and later decide to use XML files to store
|
|
365 |
data instead of a database, it is essentially just a matter of
|
|
366 |
replacing one data model with another.
|
|
367 |
|
|
368 |
\section2 The SQL Query Model
|
|
369 |
|
|
370 |
QSqlQueryModel offers a read-only model based on an SQL query.
|
|
371 |
|
|
372 |
Example:
|
|
373 |
|
|
374 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 40
|
|
375 |
|
|
376 |
After setting the query using QSqlQueryModel::setQuery(), you can
|
|
377 |
use QSqlQueryModel::record(int) to access the individual records.
|
|
378 |
You can also use QSqlQueryModel::data() and any of the other
|
|
379 |
functions inherited from QAbstractItemModel.
|
|
380 |
|
|
381 |
There's also a \l{QSqlQueryModel::setQuery()}{setQuery()}
|
|
382 |
overload that takes a QSqlQuery object and operates on its result
|
|
383 |
set. This enables you to use any features of QSqlQuery to set up
|
|
384 |
the query (e.g., prepared queries).
|
|
385 |
|
|
386 |
\section2 The SQL Table Model
|
|
387 |
|
|
388 |
QSqlTableModel offers a read-write model that works on a single
|
|
389 |
SQL table at a time.
|
|
390 |
|
|
391 |
Example:
|
|
392 |
|
|
393 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 41
|
|
394 |
|
|
395 |
QSqlTableModel is a high-level alternative to QSqlQuery for
|
|
396 |
navigating and modifying individual SQL tables. It typically
|
|
397 |
results in less code and requires no knowledge of SQL syntax.
|
|
398 |
|
|
399 |
Use QSqlTableModel::record() to retrieve a row in the table, and
|
|
400 |
QSqlTableModel::setRecord() to modify the row. For example, the
|
|
401 |
following code will increase every employee's salary by 10 per
|
|
402 |
cent:
|
|
403 |
|
|
404 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 42
|
|
405 |
|
|
406 |
You can also use QSqlTableModel::data() and
|
|
407 |
QSqlTableModel::setData(), which are inherited from
|
|
408 |
QAbstractItemModel, to access the data. For example, here's how
|
|
409 |
to update a record using
|
|
410 |
\l{QSqlTableModel::setData()}{setData()}:
|
|
411 |
|
|
412 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 43
|
|
413 |
|
|
414 |
Here's how to insert a row and populate it:
|
|
415 |
|
|
416 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 44
|
|
417 |
|
|
418 |
Here's how to delete five consecutive rows:
|
|
419 |
|
|
420 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 45
|
|
421 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 46
|
|
422 |
|
|
423 |
The first argument to QSqlTableModel::removeRows() is the index
|
|
424 |
of the first row to delete.
|
|
425 |
|
|
426 |
When you're finished changing a record, you should always call
|
|
427 |
QSqlTableModel::submitAll() to ensure that the changes are
|
|
428 |
written to the database.
|
|
429 |
|
|
430 |
When and whether you actually \e need to call submitAll() depends
|
|
431 |
on the table's \l{QSqlTableModel::editStrategy()}{edit strategy}.
|
|
432 |
The default strategy is QSqlTableModel::OnRowChange, which
|
|
433 |
specifies that pending changes are applied to the database when
|
|
434 |
the user selects a different row. Other strategies are
|
|
435 |
QSqlTableModel::OnManualSubmit (where all changes are cached in
|
|
436 |
the model until you call submitAll()) and
|
|
437 |
QSqlTableModel::OnFieldChange (where no changes are cached).
|
|
438 |
These are mostly useful when QSqlTableModel is used with a view.
|
|
439 |
|
|
440 |
QSqlTableModel::OnFieldChange seems to deliver the promise that
|
|
441 |
you never need to call submitAll() explicitly. There are two
|
|
442 |
pitfalls, though:
|
|
443 |
|
|
444 |
\list
|
|
445 |
\o Without any caching, performance may drop significantly.
|
|
446 |
\o If you modify a primary key, the record might slip through
|
|
447 |
your fingers while you are trying to populate it.
|
|
448 |
\endlist
|
|
449 |
|
|
450 |
\section2 The SQL Relational Table Model
|
|
451 |
|
|
452 |
QSqlRelationalTableModel extends QSqlTableModel to provide
|
|
453 |
support for foreign keys. A foreign key is a 1-to-1 mapping
|
|
454 |
between a field in one table and the primary key field of another
|
|
455 |
table. For example, if a \c book table has a field called \c
|
|
456 |
authorid that refers to the author table's \c id field, we say
|
|
457 |
that \c authorid is a foreign key.
|
|
458 |
|
|
459 |
\table
|
|
460 |
\row \o \inlineimage noforeignkeys.png
|
|
461 |
\o \inlineimage foreignkeys.png
|
|
462 |
\endtable
|
|
463 |
|
|
464 |
The screenshot on the left shows a plain QSqlTableModel in a
|
|
465 |
QTableView. Foreign keys (\c city and \c country) aren't resolved
|
|
466 |
to human-readable values. The screenshot on the right shows a
|
|
467 |
QSqlRelationalTableModel, with foreign keys resolved into
|
|
468 |
human-readable text strings.
|
|
469 |
|
|
470 |
The following code snippet shows how the QSqlRelationalTableModel
|
|
471 |
was set up:
|
|
472 |
|
|
473 |
\snippet examples/sql/relationaltablemodel/relationaltablemodel.cpp 0
|
|
474 |
\codeline
|
|
475 |
\snippet examples/sql/relationaltablemodel/relationaltablemodel.cpp 1
|
|
476 |
\snippet examples/sql/relationaltablemodel/relationaltablemodel.cpp 2
|
|
477 |
|
|
478 |
See the QSqlRelationalTableModel documentation for details.
|
|
479 |
*/
|
|
480 |
|
|
481 |
/*!
|
|
482 |
\page sql-presenting.html
|
|
483 |
\title Presenting Data in a Table View
|
|
484 |
|
|
485 |
\previouspage Using the SQL Model Classes
|
|
486 |
\contentspage SQL Programming
|
|
487 |
\nextpage Creating Data-Aware Forms
|
|
488 |
|
|
489 |
The QSqlQueryModel, QSqlTableModel, and QSqlRelationalTableModel
|
|
490 |
classes can be used as a data source for Qt's view classes such
|
|
491 |
as QListView, QTableView, and QTreeView. In practice, QTableView
|
|
492 |
is by far the most common choice, because an SQL result set is
|
|
493 |
essentially a two-dimensional data structure.
|
|
494 |
|
|
495 |
\image relationaltable.png A table view displaying a QSqlTableModel
|
|
496 |
|
|
497 |
The following example creates a view based on an SQL data model:
|
|
498 |
|
|
499 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 17
|
|
500 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 18
|
|
501 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 19
|
|
502 |
|
|
503 |
If the model is a read-write model (e.g., QSqlTableModel), the
|
|
504 |
view lets the user edit the fields. You can disable this by
|
|
505 |
calling
|
|
506 |
|
|
507 |
\snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 20
|
|
508 |
|
|
509 |
You can use the same model as a data source for multiple views.
|
|
510 |
If the user edits the model through one of the views, the other
|
|
511 |
views will reflect the changes immediately. The
|
|
512 |
\l{sql/tablemodel}{Table Model} example shows how it works.
|
|
513 |
|
|
514 |
View classes display a header at the top to label the columns. To
|
|
515 |
change the header texts, call
|
|
516 |
\l{QAbstractItemModel::setHeaderData()}{setHeaderData()} on the
|
|
517 |
model. The header's labels default to the table's field names.
|
|
518 |
For example:
|
|
519 |
|
|
520 |
\snippet examples/sql/relationaltablemodel/relationaltablemodel.cpp 3
|
|
521 |
|
|
522 |
QTableView also has a vertical header on the left with numbers
|
|
523 |
identifying the rows. If you insert rows programmatically using
|
|
524 |
QSqlTableModel::insertRows(), the new rows will be marked with an
|
|
525 |
asterisk (*) until they are submitted using
|
|
526 |
\l{QSqlTableModel::submitAll()}{submitAll()} or automatically
|
|
527 |
when the user moves to another record (assuming the
|
|
528 |
\l{QSqlTableModel::EditStrategy}{edit strategy} is
|
|
529 |
QSqlTableModel::OnRowChange).
|
|
530 |
|
|
531 |
\image insertrowinmodelview.png Inserting a row in a model
|
|
532 |
|
|
533 |
Likewise, if you remove rows using
|
|
534 |
\l{QSqlTableModel::removeRows()}{removeRows()}, the rows will be
|
|
535 |
marked with an exclamation mark (!) until the change is
|
|
536 |
submitted.
|
|
537 |
|
|
538 |
The items in the view are rendered using a delegate. The default
|
|
539 |
delegate, QItemDelegate, handles the most common data types (\c
|
|
540 |
int, QString, QImage, etc.). The delegate is also responsible for
|
|
541 |
providing editor widgets (e.g., a combobox) when the user starts
|
|
542 |
editing an item in the view. You can create your own delegates by
|
|
543 |
subclassing QAbstractItemDelegate or QItemDelegate. See
|
|
544 |
\l{Model/View Programming} for more information.
|
|
545 |
|
|
546 |
QSqlTableModel is optimized to operate on a single table at a
|
|
547 |
time. If you need a read-write model that operates on an
|
|
548 |
arbitrary result set, you can subclass QSqlQueryModel and
|
|
549 |
reimplement \l{QAbstractItemModel::flags()}{flags()} and
|
|
550 |
\l{QAbstractItemModel::setData()}{setData()} to make it
|
|
551 |
read-write. The following two functions make fields 1 and 2 of a
|
|
552 |
query model editable:
|
|
553 |
|
|
554 |
\snippet examples/sql/querymodel/editablesqlmodel.cpp 0
|
|
555 |
\codeline
|
|
556 |
\snippet examples/sql/querymodel/editablesqlmodel.cpp 1
|
|
557 |
|
|
558 |
The setFirstName() helper function is defined as follows:
|
|
559 |
|
|
560 |
\snippet examples/sql/querymodel/editablesqlmodel.cpp 2
|
|
561 |
|
|
562 |
The setLastName() function is similar. See the
|
|
563 |
\l{sql/querymodel}{Query Model} example for the complete source code.
|
|
564 |
|
|
565 |
Subclassing a model makes it possible to customize it in many
|
|
566 |
ways: You can provide tooltips for the items, change the
|
|
567 |
background color, provide calculated values, provide different
|
|
568 |
values for viewing and editing, handle null values specially, and
|
|
569 |
more. See \l{Model/View Programming} as well as the \l
|
|
570 |
QAbstractItemView reference documentation for details.
|
|
571 |
|
|
572 |
If all you need is to resolve a foreign key to a more
|
|
573 |
human-friendly string, you can use QSqlRelationalTableModel. For
|
|
574 |
best results, you should also use QSqlRelationalDelegate, a
|
|
575 |
delegate that provides combobox editors for editing foreign keys.
|
|
576 |
|
|
577 |
\image relationaltable.png Editing a foreign key in a relational table
|
|
578 |
|
|
579 |
The \l{sql/relationaltablemodel}{Relational Table Model} example
|
|
580 |
illustrates how to use QSqlRelationalTableModel in conjunction with
|
|
581 |
QSqlRelationalDelegate to provide tables with foreign key
|
|
582 |
support.
|
|
583 |
*/
|
|
584 |
|
|
585 |
/*!
|
|
586 |
\page sql-forms.html
|
|
587 |
\title Creating Data-Aware Forms
|
|
588 |
|
|
589 |
\previouspage Presenting Data in a Table View
|
|
590 |
\contentspage SQL Programming
|
|
591 |
|
|
592 |
Using the SQL models described above, the contents of a database can
|
|
593 |
be presented to other model/view components. For some applications,
|
|
594 |
it is sufficient to present this data using a standard item view,
|
|
595 |
such as QTableView. However, users of record-based applications often
|
|
596 |
require a form-based user interface in which data from a specific
|
|
597 |
row or column in a database table is used to populate editor widgets
|
|
598 |
on a form.
|
|
599 |
|
|
600 |
Such data-aware forms can be created with the QDataWidgetMapper class,
|
|
601 |
a generic model/view component that is used to map data from a model
|
|
602 |
to specific widgets in a user interface.
|
|
603 |
|
|
604 |
QDataWidgetMapper operates on a specific database table, mapping items
|
|
605 |
in the table on a row-by-row or column-by-column basis. As a result,
|
|
606 |
using QDataWidgetMapper with a SQL model is as simple as using it with
|
|
607 |
any other table model.
|
|
608 |
|
|
609 |
\image qdatawidgetmapper-simple.png
|
|
610 |
|
|
611 |
The \l{demos/books}{Books} demonstration shows how information can
|
|
612 |
be presented for easy access by using QDataWidgetMapper and a set of
|
|
613 |
simple input widgets.
|
|
614 |
*/
|