Sur cette page

Exemple de mappeur de widgets combinés

L'exemple Combo Widget Mapper montre comment utiliser un site QDataWidgetMapper pour faire correspondre les informations d'un modèle à des widgets spécifiques sur un formulaire.

Application avec différents champs tels que le nom, l'adresse et le type.

Nous créons une classe Window avec une interface utilisateur presque identique, sauf qu'au lieu de fournir une boîte tournante pour saisir l'âge de chaque personne, nous fournissons une boîte combinée pour permettre de classer leurs adresses comme "Domicile", "Travail" ou "Autre".

Définition de la classe de personnes

Nous définissons une structure Person contenant le nom, l'adresse et le type d'adresse pour représenter les données du modèle :

struct Person
{
private:
    Q_GADGET
    Q_PROPERTY(QString name MEMBER name)
    Q_PROPERTY(QString address MEMBER address)
    Q_PROPERTY(QString type MEMBER type)
public:

    QString name;
    QString address;
    QString type;
};

Elle est déclarée comme étant une Q_GADGET dont les membres sont des propriétés du même nom afin de pouvoir remplir facilement une QRangeModel.

Définition de la classe de fenêtre

La classe fournit un constructeur et une fente pour maintenir les boutons à jour :

class Window : public QWidget
{
    Q_OBJECT

public:
    Window(QWidget *parent = nullptr);

private slots:
    void updateButtons(int row);

private:
    QLineEdit *nameEdit;
    QTextEdit *addressEdit;
    QComboBox *typeComboBox;
    QPushButton *nextButton;
    QPushButton *previousButton;
    QList<Person> data;
    QRangeModel *model;
    QDataWidgetMapper *mapper;
};

Outre l'objet QDataWidgetMapper et les contrôles utilisés pour constituer l'interface utilisateur, nous utilisons une <Personne> QList pour contenir nos données et une QRangeModel pour les exploiter.

Mise en œuvre de la classe Window

Le constructeur de la classe Window peut être expliqué en plusieurs parties. Dans la première partie, nous mettons en place les widgets utilisés pour l'interface utilisateur :

Window::Window(QWidget *parent)
    : QWidget(parent),
      nameEdit(new QLineEdit),
      addressEdit(new QTextEdit),
      typeComboBox(new QComboBox),
      nextButton(new QPushButton(tr("&Next"))),
      previousButton(new QPushButton(tr("&Previous"))),

La liste des personnes est remplie à l'aide d'une liste d'initaliseurs, qui est ensuite transmise à la classe QRangeModel:

      data{Person{u"Alice"_s,  u"<qt>123 Main Street<br/>Market Town</qt>"_s,                      u"0"_s},
           Person{u"Bob"_s,    u"<qt>PO Box 32<br/>Mail Handling Service<br/>Service City</qt>"_s, u"1"_s},
           Person{u"Carol"_s,  u"<qt>The Lighthouse<br/>Remote Island</qt>"_s,                     u"2"_s},
           Person{u"Donald"_s, u"<qt>47338 Park Avenue<br/>Big City</qt>"_s,                       u"0"_s},
           Person{u"Emma"_s,   u"<qt>Research Station<br/>Base Camp<br/>Big Mountain</qt>"_s,      u"2"_s}},
      model(new QRangeModel(data, this)),
      mapper(new QDataWidgetMapper(this))

Notez que nous configurons le mappage de la boîte combinée de la même manière que pour les autres widgets, mais que nous lui appliquons son propre modèle contenant des informations sur les types d'adresse, de sorte qu'elle affichera la chaîne du type d'adresse plutôt que les données du modèle contenant les données sur chaque personne :

    typeComboBox->setModel(new QStringListModel({ tr("Home"), tr("Work"), tr("Other") }, this));

Ensuite, nous configurons le mappeur de widgets, en reliant chaque widget d'entrée à une colonne du modèle spécifié par l'appel à setModel() :

    mapper->setModel(model);
    mapper->addMapping(nameEdit, 0);
    mapper->addMapping(addressEdit, 1);
    mapper->addMapping(typeComboBox, 2, "currentIndex");

Pour la liste déroulante, nous passons un argument supplémentaire pour indiquer au cartographe de widgets quelle propriété doit être liée aux valeurs du modèle. Ainsi, l'utilisateur peut sélectionner un élément dans la liste déroulante et la valeur correspondante stockée dans la propriété currentIndex du widget sera stockée dans le modèle.

Le reste du constructeur établit les connexions et les mises en page :

    connect(previousButton, &QAbstractButton::clicked,
            mapper, &QDataWidgetMapper::toPrevious);
    connect(nextButton, &QAbstractButton::clicked,
            mapper, &QDataWidgetMapper::toNext);
    connect(mapper, &QDataWidgetMapper::currentIndexChanged,
            this, &Window::updateButtons);

    auto *formLayout = new QFormLayout;
    formLayout->addRow(tr("Na&me:"), nameEdit);
    formLayout->addRow(tr("&Address:"), addressEdit);
    formLayout->addRow(tr("&Type:"), typeComboBox);

    auto *buttonLayout = new QVBoxLayout;
    buttonLayout->addWidget(previousButton);
    buttonLayout->addWidget(nextButton);
    buttonLayout->addStretch();

    auto *mainLayout = new QHBoxLayout(this);
    mainLayout->addLayout(formLayout);
    mainLayout->addLayout(buttonLayout);

    setWindowTitle(tr("Delegate Widget Mapper"));
    mapper->toFirst();
}

Mappage du modèle à la vue à l'aide d'un délégué

Nous montrons l'implémentation du slot updateButtons() par souci d'exhaustivité :

void Window::updateButtons(int row)
{
    previousButton->setEnabled(row > 0);
    nextButton->setEnabled(row < model->rowCount() - 1);
}

Résumé et lectures complémentaires

L'utilisation d'un modèle distinct pour la liste déroulante permet d'obtenir un menu de choix distinct des données stockées dans le modèle principal. L'utilisation d'un mappage nommé qui relie la propriété currentIndex de la liste déroulante à une colonne du modèle nous permet de stocker une valeur de consultation dans le modèle.

Cependant, lorsque nous lisons le modèle en dehors du contexte du mappeur de widgets, nous devons connaître le site typeModel pour donner un sens à ces valeurs de consultation. Il serait utile de pouvoir stocker à la fois les données et les choix détenus par typeModel en un seul endroit. Ceci est couvert par l'exemple SQL Widget Mapper.

Exemple de projet @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.