【初心者向け】Qt WidgetsでQAbstractItemView::selectedIndexes()を使いこなして効率アップ


QAbstractItemView::selectedIndexes()は、Qt Widgetsにおける抽象的なアイテムビュークラスQAbstractItemViewが提供するメソッドの一つです。このメソッドは、現在選択されているアイテムのインデックスリストを取得するために使用されます。

使い方

selectedIndexes()メソッドは、以下の形式で使用されます。

QModelIndexList selectedIndexes() const;

このメソッドは、QModelIndexList型のリストを返します。このリストには、現在選択されているすべてのアイテムのインデックスが含まれています。

以下のコードは、QTableViewで選択されているすべての行を取得する方法を示しています。

QTableView *tableView;
QModelIndexList selectedIndexes = tableView->selectionModel()->selectedIndexes();

for (QModelIndex index : selectedIndexes) {
    int row = index.row();
    // ... 行ごとに処理を行う
}
  • QModelIndexには、親インデックスなどの情報が含まれています。これらの情報を使用して、選択されているアイテムに関する詳細を取得することができます。
  • QModelIndexListは、QModelIndex型の要素を持つリストです。QModelIndexは、モデル内のアイテムを識別するために使用される構造体です。
  • selectedIndexes()メソッドは、保護されたメンバー関数であることに注意してください。そのため、直接呼び出すことはできません。代わりに、selectionModel()メソッドを使用して、アイテムビューの選択モデルを取得し、そのモデルのselectedIndexes()メソッドを呼び出す必要があります。


QTableViewで選択されているすべての行を取得する

QTableView *tableView;
QModelIndexList selectedIndexes = tableView->selectionModel()->selectedIndexes();

for (QModelIndex index : selectedIndexes) {
    int row = index.row();
    // ... 行ごとに処理を行う
}
  1. まず、QTableViewオブジェクトのポインタtableViewを宣言します。
  2. 続いて、tableViewselectionModel()メソッドを使用して、アイテムビューの選択モデルを取得します。
  3. 次に、選択モデルのselectedIndexes()メソッドを使用して、選択されているすべてのアイテムのインデックスリストを取得します。
  4. 最後に、forループを使用して、インデックスリスト内の各インデックスを反復処理します。
  5. ループ内では、index.row()メソッドを使用して、インデックスに対応する行番号を取得します。
  6. 取得した行番号を使用して、選択されている行ごとに処理を行います。

以下のコードは、選択されている行のセル値をコンソールに出力する例です。

for (QModelIndex index : selectedIndexes) {
    int row = index.row();
    for (int col = 0; col < tableView->model()->columnCount(); ++col) {
        QModelIndex cellIndex = model->index(row, col);
        QString text = cellIndex.data().toString();
        std::cout << text << " ";
    }
    std::cout << std::endl;
}

QListViewで選択されているすべてのアイテムを取得する

QListView *listView;
QModelIndexList selectedIndexes = listView->selectionModel()->selectedIndexes();

for (QModelIndex index : selectedIndexes) {
    QString text = index.data().toString();
    // ... アイテムごとに処理を行う
}

説明

このコードは、QListViewで選択されているすべてのアイテムを取得する方法を示しています。

  1. まず、QListViewオブジェクトのポインタlistViewを宣言します。
  2. 続いて、listViewselectionModel()メソッドを使用して、アイテムビューの選択モデルを取得します。
  3. 次に、選択モデルのselectedIndexes()メソッドを使用して、選択されているすべてのアイテムのインデックスリストを取得します。
  4. 最後に、forループを使用して、インデックスリスト内の各インデックスを反復処理します。
  5. ループ内では、index.data().toString()メソッドを使用して、インデックスに対応するアイテムのテキストを取得します。
  6. 取得したテキストを使用して、選択されているアイテムごとに処理を行います。

以下のコードは、選択されているアイテムのテキストをコンソールに出力する例です。

for (QModelIndex index : selectedIndexes) {
    QString text = index.data().toString();
    std::cout << text << std::endl;
}
QTreeView *treeView;
QModelIndexList selectedIndexes = treeView->selectionModel()->selectedIndexes();

for (QModelIndex index : selectedIndexes) {
    if (index.model()->hasChildren(index)) {
        // ノード
        QString text = index.data().toString();
        // ... ノードごとに処理を行う
    } else {
        // 葉
        QString text = index.data().toString();
        // ... 葉ごとに処理を行う
    }
}

説明

このコードは、QTreeViewで選択されているすべてのノードを取得する方法を示しています。

  1. まず、QTreeViewオブジェクトのポインタtreeViewを宣言します。
  2. 続いて、treeViewselectionModel()メソッドを使用して、アイテムビューの選択モデルを取得します。
  3. 次に、選択モデルのselectedIndexes()メソッドを使用して、選択されているすべてのアイテムのインデックスリストを取得します。
  4. 最後に、forループを使用して、インデックスリスト内の各インデックスを反復処理します。
  5. ループ内では、index.model()->hasChildren(index)メソッドを使用して、インデックスに対応するアイテムがノードかどうかを判断します。
  6. インデックスがノードの場合、index.data().toString()メソッドを使用して、ノードのテキストを取得します。
  7. 取得したテキストを使用して、選択されているノードごとに処理を行います。
  8. インデックスが葉の場合


行または列のインデックスを取得する

QAbstractItemView::selectionModel()には、現在選択されている行または列のインデックスを取得するためのメソッドが用意されています。これらのメソッドは以下の通りです。

  • selectedColumns():現在選択されている列のインデックスリストを返します。
  • selectedRows():現在選択されている行のインデックスリストを返します。

これらのメソッドは、行または列全体が選択されている場合にのみ有効です。部分的に選択されている行または列の場合は使用できません。

QTableView *tableView;

QModelIndexList selectedRows = tableView->selectionModel()->selectedRows();
for (QModelIndex index : selectedRows) {
    int row = index.row();
    // ... 行ごとに処理を行う
}

アイテムデータを取得する

QAbstractItemView::itemData()メソッドを使用して、選択されているアイテムのデータを取得することができます。このメソッドは以下の形式で使用されます。

QVariant itemData(const QModelIndex &index, int role = Qt::DisplayRole) const;

このメソッドは、QVariant型の値を返します。この値は、アイテムのデータの種類によって異なります。

QTableView *tableView;

QModelIndexList selectedIndexes = tableView->selectionModel()->selectedIndexes();
for (QModelIndex index : selectedIndexes) {
    QString text = index.data().toString();
    // ... アイテムごとに処理を行う
}

カスタム選択モデルを使用する

独自の選択モデルを実装することで、QAbstractItemView::selectedIndexes()とは異なる方法で選択されたアイテムを取得することができます。

class MySelectionModel : public QItemSelectionModel {
public:
    QModelIndexList selectedIndexes(const QModelIndex &parent = QModelIndex()) const override;
};

class MyTableView : public QTableView {
public:
    MyTableView(QWidget *parent = nullptr);

protected:
    QItemSelectionModel *createSelectionModel(const QAbstractItemModel *model) const override;
};

QModelIndexList MySelectionModel::selectedIndexes(const QModelIndex &parent) const {
    // ... カスタムロジックを使用して選択されたアイテムを取得する
}

MyTableView::MyTableView(QWidget *parent) : QTableView(parent) {
    setSelectionModel(new MySelectionModel(this));
}

シグナルとスロットを使用する

QAbstractItemViewクラスは、選択が変更されたときに発生するシグナルをいくつか提供しています。これらのシグナルに接続することで、選択されたアイテムに関する情報を取得することができます。

QTableView *tableView;

connect(tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MyClass::onSelectionChanged);

void MyClass::onSelectionChanged(const QSelectionModel &selectionModel) {
    QModelIndexList selectedIndexes = selectionModel.selectedIndexes();
    // ... 選択されたアイテムごとに処理を行う
}