「QMLのコントロール - ListModelのカスタム」の版間の差分

📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
(同じ利用者による、間の2版が非表示)
172行目: 172行目:
<br>
<br>
===== roleNamesメソッド =====
===== roleNamesメソッド =====
roleNamesメソッドは必ずオーバーライドする必要がある。<br>
このメソッドは、QML側でアクセスするプロパティ名を定義するものである。<br>
<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  // QAbstractListModelクラスのオーバーライドが必須のメソッド
  // QAbstractListModelクラスのオーバーライドが必須のメソッド
193行目: 196行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== データ操作メソッド ====
==== データ操作メソッド ====
===== appendItemメソッド =====
===== appendItemメソッド =====
298行目: 302行目:
<br><br>
<br><br>


== カスタムリストモデルの使用 ==
== ListViewとの連携 ==
==== エントリポイント ====
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
#include "CustomListModel.h"  // カスタムリストモデルクラスの定義
// ...略
  int main(int argc, char *argv[])
  int main(int argc, char *argv[])
  {
  {
315行目: 324行目:
   </syntaxhighlight>
   </syntaxhighlight>
<br>
<br>
==== カスタムリストモデルの呼び出し ====
  <syntaxhighlight lang="qml">
  <syntaxhighlight lang="qml">
  import QtQuick
  import QtQuick
432行目: 442行目:
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br>
==== カスタムリストモデルクラスの定義 ====
<syntaxhighlight lang="c++">
// CustomListModel.h
#include <QAbstractListModel>
#include <QVector>
// カスタムデータ構造の定義
struct CustomData {
    QString    name;
    int        value;
    QStringList tags;  // 配列データ
};
class CustomListModel : public QAbstractListModel
{
    Q_OBJECT
private:
    // モデルのデータを保持するコンテナ
    QVector<CustomData> m_items;
public:
    // モデルで使用するロールの定義
    // QML側からアクセスする時に使用する識別子
    enum CustomRoles {
        NameRole = Qt::UserRole + 1,
        ValueRole,
        TagsRole
    };
    explicit CustomListModel(QObject *parent = nullptr) : QAbstractListModel(parent)
    {}
    // QAbstractListModelの必須オーバーライド関数
    // データの行数を取得する
    int rowCount(const QModelIndex &parent = QModelIndex()) const override
    {
      // 親インデックスが有効な場合は0を返す
      // リストモデルでは子アイテムを持たないため
      if (parent.isValid()) return 0;
      return m_items.size();
    }
    // 指定されたインデックスとロールに対応するデータを取得する
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
    {
      // インデックスの有効性確認
      if (!index.isValid() || index.row() >= m_items.size()) return QVariant();
      // 指定された行のデータを取得
      const CustomData &item = m_items[index.row()];
      // ロールに応じて適切なデータを返す
      switch (role) {
          case NameRole:  return item.name;
          case ValueRole: return item.value;
          case TagsRole:  return QVariant::fromValue(item.tags);
          default:        return QVariant();
      }
    }
    // ロール名をQML側に公開する
    QHash<int, QByteArray> roleNames() const override
    {
      // ロール名とロールIDのマッピングを定義
      // これにより、QML側でロール名を使用してデータにアクセス可能となる
      QHash<int, QByteArray> roles;
      roles[NameRole] = "name";
      roles[ValueRole] = "value";
      roles[TagsRole] = "tags";
      return roles;
    }
    // データ操作用メソッド
    // QML側から呼び出し可能なメソッド
    Q_INVOKABLE void appendItem(const QString &name, int value, const QStringList &tags)
    {
      // データ追加開始を通知
      beginInsertRows(QModelIndex(), m_items.size(), m_items.size());
      // 新しいアイテムを追加
      CustomData item{name, value, tags};
      m_items.append(item);
      // データ追加完了を通知
      endInsertRows();
    }
    Q_INVOKABLE void removeItem(int index)
    {
      // インデックスの有効性確認
      if (index < 0 || index >= m_items.size()) return;
      // データ削除開始を通知
      beginRemoveRows(QModelIndex(), index, index);
      // アイテムを削除
      m_items.removeAt(index);
      // データ削除完了を通知
      endRemoveRows();
    }
    Q_INVOKABLE void clearItems()
    {
      // データが存在しない場合
      if (m_items.isEmpty()) return;
      // データ削除開始を通知
      beginRemoveRows(QModelIndex(), 0, m_items.size() - 1);
      // 全てのアイテムを削除
      m_items.clear();
      // データ削除完了を通知
      endRemoveRows();
    }
    Q_INVOKABLE void updateItem(int index, const QString &name, int value, const QStringList &tags)
    {
      // インデックスの有効性確認
      if (index < 0 || index >= m_items.size()) return;
      // アイテムを更新
      CustomData &item = m_items[index];
      item.name  = name;
      item.value = value;
      item.tags  = tags;
      // データ更新を通知
      // この通知により、QMLビューが自動的に更新される
      emit dataChanged(createIndex(index, 0), createIndex(index, 0));
    }
};
</syntaxhighlight>
<br>
<br><br>
<br><br>