Viadeo Twitter Google Bookmarks ! Facebook Digg del.icio.us MySpace Yahoo MyWeb Blinklist Netvouz Reddit Simpy StumbleUpon Bookmarks Windows Live Favorites 
Logo Documentation Qt ·  Page d'accueil  ·  Toutes les classes  ·  Classes principales  ·  Annotées  ·  Classes groupées  ·  Modules  ·  Fonctions  · 

Cached Table Example

Files:

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.

The example consists of a single class, 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.

TableEditor Class Definition

The TableEditor class inherits QDialog making the table editor widget a top-level dialog window.

    class TableEditor : public QDialog
    {
        Q_OBJECT

    public:
        TableEditor(const QString &tableName, QWidget *parent = 0);

    private slots:
        void submit();

    private:
        QPushButton *submitButton;
        QPushButton *revertButton;
        QPushButton *quitButton;
        QSqlTableModel *model;
    };

The 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 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 submit() slot in additon to the model and the editor's buttons.

Connecting to a Database
Before we can use the TableEditor class, we must create a connection to the database containing the table we want to edit:
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        if (!createConnection())
            return 1;

        TableEditor editor("person");
        editor.show();
        return editor.exec();
    }

The createConnection() function is a helper function provided for convenience. It is defined in the connection.h file which is located in the sql example directory (all the examples in the sql directory use this function to connect to a database).

    static bool createConnection()
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName(":memory:");
        if (!db.open()) {
            QMessageBox::critical(0, qApp->tr("Cannot open database"),
                qApp->tr("Unable to establish a database connection.\n"
                         "This example needs SQLite support. Please read "
                         "the Qt SQL driver documentation for information how "
                         "to build it.\n\n"
                         "Click Cancel to exit."), QMessageBox::Cancel,
                         QMessageBox::NoButton);
            return false;
        }

        QSqlQuery query;
        query.exec("create table person (id int primary key, "
                   "firstname varchar(20), lastname varchar(20))");
        query.exec("insert into person values(101, 'Danny', 'Young')");
        query.exec("insert into person values(102, 'Christine', 'Holand')");
        query.exec("insert into person values(103, 'Lars', 'Gordon')");
        query.exec("insert into person values(104, 'Roberto', 'Robitaille')");
        query.exec("insert into person values(105, 'Maria', 'Papadopoulos')");
        return true;
    }

The 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.

TableEditor Class Implementation

The class implementation consists of only two functions, the constructor and the submit() slot. In the constructor we create and customize the data model and the various window elements:

    TableEditor::TableEditor(const QString &tableName, QWidget *parent)
        : QDialog(parent)
    {
        model = new QSqlTableModel(this);
        model->setTable(tableName);
        model->setEditStrategy(QSqlTableModel::OnManualSubmit);
        model->select();

        model->setHeaderData(0, Qt::Horizontal, tr("ID"));
        model->setHeaderData(1, Qt::Horizontal, tr("First name"));
        model->setHeaderData(2, Qt::Horizontal, tr("Last name"));

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 setHeaderData() function the model inherits from the QSqlQueryModel class.

        QTableView *view = new QTableView;
        view->setModel(model);

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 editTriggers property the view inherits from the QAbstractItemView class.

We pass our model to the view, using the setModel() function, to make the view present our data.

        submitButton = new QPushButton(tr("Submit"));
        submitButton->setDefault(true);
        revertButton = new QPushButton(tr("&Revert"));
        quitButton = new QPushButton(tr("Quit"));

        connect(submitButton, SIGNAL(clicked()), this, SLOT(submit()));
        connect(revertButton, SIGNAL(clicked()), model, SLOT(revertAll()));
        connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));

The TableEditor's buttons are regular QPushButton objects. We connect the Quit button to the table editor's close() slot, and the Submit button to our private submit() slot. The latter slot will take care of the data transactions. Finally, we connect the Revert button to our model's revertAll() slot, reverting all pending changes (restoring the original data).

        QVBoxLayout *buttonLayout = new QVBoxLayout;
        buttonLayout->addWidget(submitButton);
        buttonLayout->addWidget(revertButton);
        buttonLayout->addWidget(quitButton);
        buttonLayout->addStretch(1);

        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->addWidget(view);
        mainLayout->addLayout(buttonLayout);
        setLayout(mainLayout);

        setWindowTitle(tr("Cached Table"));
    }

In the end we add all the buttons and the table view to a layout, install the layout on the table editor widget, and set the editor's window title.

    void TableEditor::submit()
    {
        model->database().transaction();
        if (model->submitAll()) {
            model->database().commit();
        } else {
            model->database().rollback();
            QMessageBox::warning(this, tr("Cached Table"),
                                 tr("The database reported an error: %1")
                                 .arg(model->lastError().text()));
        }
    }

The submit() slot is called whenever the users hit the 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.

See also:

A complete list of Qt's SQL Database Classes, and the Model/View Programming documentation.

Publicité

Best Of

Actualités les plus lues

Semaine
Mois
Année
  1. Microsoft ouvre aux autres compilateurs C++ AMP, la spécification pour la conception d'applications parallèles C++ utilisant le GPU 22
  2. Les développeurs ignorent-ils trop les failles découvertes dans leur code ? Prenez-vous en compte les remarques des autres ? 17
  3. RIM : « 13 % des développeurs ont gagné plus de 100 000 $ sur l'AppWord », Qt et open-source au menu du BlackBerry DevCon Europe 0
  4. « Quelque chose ne va vraiment pas avec les développeurs "modernes" », un développeur à "l'ancienne" critique la multiplication des bibliothèques 10
  5. BlackBerry 10 : premières images du prochain OS de RIM qui devrait intégrer des widgets et des tuiles inspirées de Windows Phone 0
  6. Adieu qmake, bienvenue qbs : Qt Building Suite, un outil déclaratif et extensible pour la compilation de projets Qt 17
  7. Quelles nouveautés de C++11 Visual C++ doit-il rapidement intégrer ? Donnez-nous votre avis 10
Page suivante

Le Qt Quarterly au hasard

Logo

Déployer dans le Bazaar

Qt Quarterly est la revue trimestrielle proposée par Nokia et à destination des développeurs Qt. Ces articles d'une grande qualité technique sont rédigés par des experts Qt. Lire l'article.

Communauté

Ressources

Liens utiles

Contact

  • Vous souhaitez rejoindre la rédaction ou proposer un tutoriel, une traduction, une question... ? Postez dans le forum Contribuez ou contactez-nous par MP ou par email (voir en bas de page).

Qt dans le magazine

Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia. Qt 4.1
Copyright © 2012 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon, vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter ou par MP !
 
 
 
 
Partenaires

Hébergement Web