Drill Down Example

Image non disponible

Screenshot of the Drill Down Example

When running the example application, a user can retrieve information about each item by clicking the corresponding image. The application pops up an information window displaying the data, and allows the users to alter the description as well as the image. The main view will be updated when the users submit their changes.

The example consists of three classes:

  • ImageItem is a custom graphics item class used to display the images.

  • View is the main application widget allowing the user to browse through the various items.

  • InformationWindow displays the requested information, allowing the users to alter it and submit their changes to the database.

We will first take a look at the 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 View class, and the associated ImageItem class.

InformationWindow Class Definition

The InformationWindow class is a custom widget inheriting QWidget:

 
Sélectionnez
class InformationWindow : public QDialog
{
    Q_OBJECT

public:
    InformationWindow(int id, QSqlRelationalTableModel *items,
                      QWidget *parent = nullptr);

    int id() const;

signals:
    void imageChanged(int id, const QString &fileName);

When we create an information window, we pass the associated item 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 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.

 
Sélectionnez
private slots:
    void revert();
    void submit();
    void enableButtons(bool enable = true);

Since we allow the users to alter some of the data, we must provide functionality for reverting and submitting their changes. The enableButtons() slot is provided for convenience to enable and disable the various buttons when required.

 
Sélectionnez
private:
    void createButtons();

    int itemId;
    QString displayedImage;

    QComboBox *imageFileEditor = nullptr;
    QLabel *itemText = nullptr;
    QTextEdit *descriptionEditor = nullptr;

    QPushButton *closeButton = nullptr;
    QPushButton *submitButton = nullptr;
    QPushButton *revertButton = nullptr;
    QDialogButtonBox *buttonBox = nullptr;

    QDataWidgetMapper *mapper = nullptr;
};

The createButtons() function is also a convenience function, provided to simplify the constructor. As mentioned above we store the item ID for future reference. We also store the name of the currently displayed image file to be able to determine when to emit the imageChanged() signal.

The information window uses the QLabel class to display the name of an item. 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 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.

InformationWindow Class Implementation

The constructor takes three arguments: an item 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.

 
Sélectionnez