このページでは

Combo Widget Mapper の例

「Combo Widget Mapper」の例では、QDataWidgetMapper を使用して、モデルからの情報をフォーム上の特定のウィジェットにマッピングする方法を示しています。

「氏名」、「住所」、「種類」などのさまざまな項目を含む申請書

Window クラスを作成します。ユーザーインターフェースはほぼ同じですが、各人の年齢を入力するためのスピンボックスの代わりに、住所を「自宅」、「職場」、または「その他」に分類するためのコンボボックスを用意しています。

Personクラスの定義

モデルデータを表すために、名前、住所、および住所タイプを含む構造体 `Person ` を定義します:

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

QRangeModel に簡単にデータを設定できるように、メンバーを同名のプロパティとするQ_GADGET として宣言します。

ウィンドウクラスの定義

このクラスは、コンストラクタと、ボタンの状態を最新に保つためのスロットを提供します:

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

QDataWidgetMapper オブジェクトやユーザーインターフェースを構成するコントロールに加え、データを保持するためのQList<Person>と、それを操作するQRangeModel を使用します。

ウィンドウクラスの実装

Window クラスのコンストラクタは、いくつかの部分に分けて説明できます。最初の部分では、ユーザーインターフェースに使用されるウィジェットを設定します:

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"))),

人物リストは初期化リストを使用して初期化され、その後、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))

コンボボックスのマッピングは他のウィジェットと同様の方法で設定しますが、各人物に関するデータを含むモデルからのデータではなく、住所の種類を示す文字列が表示されるよう、住所の種類に関する情報を保持する独自のモデルを適用している点に注意してください:

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

次に、ウィジェットマッパーを設定し、各入力ウィジェットを、setModel() の呼び出しで指定されたモデルの列に関連付けます:

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

コンボボックスの場合、モデルからの値と関連付けるプロパティをウィジェットマッパーに指定するために、追加の引数を渡します。その結果、ユーザーがコンボボックスから項目を選択すると、ウィジェットのcurrentIndex プロパティに格納されている対応する値がモデルに保存されます。

コンストラクタの残りの部分では、接続とレイアウトの設定を行います:

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

デリゲートを使用したモデルからビューへのマッピング

完全を期すために、updateButtons() スロットの実装を示します:

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

まとめと参考資料

コンボボックス用に別のモデルを使用することで、メインモデルに格納されたデータとは独立した選択肢のメニューを提供できます。コンボボックスのcurrentIndex プロパティをモデルの列に関連付ける名前付きマッピングを使用することで、モデル内にルックアップ値を効果的に格納できるようになります。

ただし、ウィジェットマッパーのコンテキスト外でモデルを読み込む場合、これらのルックアップ値を正しく解釈するには、typeModel に関する情報が必要です。typeModel が保持するデータと選択肢の両方を1か所に保存できれば便利です。これについては、「SQL Widget Mapper Example」で解説されています。

サンプルプロジェクト @ 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.