En esta página

Ejemplo de asignador de widgets combinado

El ejemplo Combo Widget Mapper muestra cómo utilizar QDataWidgetMapper para asignar información de un modelo a widgets específicos de un formulario.

Aplicación con varios campos como Nombre, Dirección y Tipo

Creamos una clase Window con una interfaz de usuario casi idéntica, excepto que, en lugar de proporcionar un cuadro giratorio para que se pueda introducir la edad de cada persona, proporcionamos un cuadro combinado para permitir que sus direcciones se clasifiquen como "Casa", "Trabajo" u "Otro".

Definición de la clase Persona

Definimos una estructura Person que contiene el nombre, la dirección y el tipo de dirección para representar los datos del modelo:

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;
};

Se declara como un Q_GADGET con los miembros que serán propiedades del mismo nombre para poder rellenar convenientemente un QRangeModel.

Definición de la clase Window

La clase proporciona un constructor y una ranura para mantener actualizados los botones:

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;
};

Además del objeto QDataWidgetMapper y los controles utilizados para componer la interfaz de usuario, utilizamos un QList<Persona> para contener nuestros datos y un QRangeModel que opera sobre ellos.

Implementación de la clase Window

El constructor de la clase Window se puede explicar en varias partes. En la primera parte, configuramos los widgets utilizados para la interfaz de usuario:

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 lista de personas se rellena utilizando una lista de initalizadores, que luego se pasa a 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))

Observe que configuramos el mapeo del cuadro combinado de la misma forma que para otros widgets, pero que le aplicamos su propio modelo que contiene información sobre los tipos de dirección, de forma que mostrará la cadena del tipo de dirección en lugar de los datos del modelo que contiene datos sobre cada persona:

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

A continuación, configuramos el mapeador de widgets, relacionando cada widget de entrada con una columna del modelo especificado por la llamada a setModel():

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

Para el cuadro combinado, pasamos un argumento adicional para indicar al mapeador de widgets qué propiedad debe relacionar con los valores del modelo. Como resultado, el usuario puede seleccionar un elemento del cuadro combinado, y el valor correspondiente almacenado en la propiedad currentIndex del widget se almacenará en el modelo.

El resto del constructor configura las conexiones y los diseños:

    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();
}

Asignación del modelo a la vista mediante un delegado

Mostramos la implementación de la ranura updateButtons() para completar:

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

Resumen y lecturas adicionales

El uso de un modelo separado para el cuadro combinado proporciona un menú de opciones separado de los datos almacenados en el modelo principal. El uso de una asignación con nombre que relaciona la propiedad currentIndex del cuadro combinado con una columna del modelo nos permite almacenar un valor de búsqueda en el modelo.

Sin embargo, cuando leemos el modelo fuera del contexto del widget mapper, necesitamos conocer typeModel para dar sentido a estos valores de búsqueda. Sería útil poder almacenar tanto los datos como las opciones de typeModel en un solo lugar. Esto está cubierto por el SQL Widget Mapper Example.

Proyecto de ejemplo @ 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.