Qt: プログラマーなら知っておきたい!QListView::isIndexHidden() 関数の裏技


QListView::isIndexHidden()関数は、指定されたモデルインデックスがビューで非表示になっているかどうかを判断します。これは、アイテムが折り畳まれたり、親アイテムが非表示になったりしている場合に役立ちます。

関数のプロトタイプ

bool QListView::isIndexHidden(const QModelIndex &index) const;

引数

  • index: 検査対象のモデルインデックス

戻り値

  • インデックスが非表示の場合はtrue、そうでない場合はfalse

詳細

QListView::isIndexHidden()関数は、ビュー内のアイテムの可視性を決定するさまざまな要因を考慮します。これらには以下が含まれます。

  • 絞り込み条件: ビューに絞り込み条件が適用されている場合、条件に一致しないアイテムは非表示になります。
  • 折りたたみ状態: アイテムが折り畳まれている場合、そのすべての子アイテムも非表示になります。
  • 親アイテムの状態: 親アイテムが非表示の場合、そのすべての子アイテムも非表示になります。

次の例では、QListView::isIndexHidden()を使用して、モデルインデックスが非表示かどうかを確認します。

QModelIndex index = model->index(row, 0);

if (listView->isIndexHidden(index)) {
    // インデックスは非表示です
} else {
    // インデックスは表示されています
}
  • モデルインデックスが非表示かどうかを判断する別の方法は、QAbstractItemView::visualRect()関数を使用してアイテムの視覚的な矩形を取得し、それがビュー内の表示領域内にあるかどうかを確認することです。
  • QListView::isRowHidden()関数を使用して、行全体が非表示になっているかどうかを確認することもできます。


例 1: 親アイテムの状態による非表示

この例では、親アイテムが非表示の場合、そのすべての子アイテムも非表示になることを示します。

#include <QApplication>
#include <QListView>
#include <QStandardItemModel>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // モデルを作成
    QStandardItemModel model;
    model.setHorizontalHeaderLabels({"Item 1", "Item 2"});

    // 親アイテムを追加
    QStandardItem *parentItem = new QStandardItem("Parent Item");
    model.appendRow(parentItem);

    // 子アイテムを追加
    parentItem->appendRow(new QStandardItem("Child Item 1"));
    parentItem->appendRow(new QStandardItem("Child Item 2"));

    // リストビューを作成
    QListView listView;
    listView.setModel(&model);

    // 親アイテムを非表示にする
    parentItem->setData(Qt::UserRole, true);

    // 子アイテムが非表示かどうかを確認
    QModelIndex childIndex1 = model.index(0, 0, parentItem);
    QModelIndex childIndex2 = model.index(1, 0, parentItem);

    if (listView.isIndexHidden(childIndex1)) {
        qDebug() << "Child Item 1 is hidden";
    } else {
        qDebug() << "Child Item 1 is visible";
    }

    if (listView.isIndexHidden(childIndex2)) {
        qDebug() << "Child Item 2 is hidden";
    } else {
        qDebug() << "Child Item 2 is visible";
    }

    listView.show();

    return app.exec();
}

このコードを実行すると、次の出力がコンソールに表示されます。

Child Item 1 is hidden
Child Item 2 is hidden

例 2: 折りたたみ状態による非表示

この例では、アイテムが折り畳まれている場合、そのすべての子アイテムも非表示になることを示します。

#include <QApplication>
#include <QListView>
#include <QStandardItemModel>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // モデルを作成
    QStandardItemModel model;
    model.setHorizontalHeaderLabels({"Item 1", "Item 2"});

    // 親アイテムを追加
    QStandardItem *parentItem = new QStandardItem("Parent Item");
    model.appendRow(parentItem);

    // 子アイテムを追加
    parentItem->appendRow(new QStandardItem("Child Item 1"));
    parentItem->appendRow(new QStandardItem("Child Item 2"));

    // リストビューを作成
    QListView listView;
    listView.setModel(&model);

    // 親アイテムを折りたたむ
    listView.setIndexExpanded(parentItem->index(), false);

    // 子アイテムが非表示かどうかを確認
    QModelIndex childIndex1 = model.index(0, 0, parentItem);
    QModelIndex childIndex2 = model.index(1, 0, parentItem);

    if (listView.isIndexHidden(childIndex1)) {
        qDebug() << "Child Item 1 is hidden";
    } else {
        qDebug() << "Child Item 1 is visible";
    }

    if (listView.isIndexHidden(childIndex2)) {
        qDebug() << "Child Item 2 is hidden";
    } else {
        qDebug() << "Child Item 2 is visible";
    }

    listView.show();

    return app.exec();
}
Child Item 1 is hidden
Child Item 2 is hidden

例 3: 絞り込み条件による非表示

この例では、ビューに絞り込み条件が適用されている場合、条件に一致しないアイテムが非表示になることを示します。

#include <QApplication>
#include <QListView>
#include <QStandardItemModel>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    // モデルを作成
    QStandardItemModel model;
    model.setHorizontalHeaderLabels({"Item 1", "Item 2"});

    // アイテムを追加
    model.appendRow(new


代替方法

  • モデルインデックスが非表示になる可能性のある要因 (親アイテムの状態、折りたたみ状態、絞り込み条件など) を個別にチェックする。
  • QAbstractItemView::visualRect() 関数を使用して、アイテムの視覚的な矩形を取得し、それがビュー内の表示領域内にあるかどうかを確認する。

詳細

QAbstractItemView::visualRect() 関数

QAbstractItemView::visualRect() 関数は、モデルインデックスに対応するアイテムの視覚的な矩形を返します。この矩形を使用して、アイテムがビュー内の表示領域内にあるかどうかを確認できます。

QModelIndex index = model->index(row, 0);
QRect visualRect = listView->visualRect(index);

if (visualRect.intersects(listView->viewportRect())) {
    // インデックスは表示されています
} else {
    // インデックスは非表示です
}

この方法は、特にアイテムが部分的にしか表示されていない場合や、ビューがスクロールされている場合に役立ちます。

個別の要因のチェック

モデルインデックスが非表示になる可能性のある要因 (親アイテムの状態、折りたたみ状態、絞り込み条件など) を個別にチェックすることもできます。

QModelIndex index = model->index(row, 0);

// 親アイテムの状態をチェック
if (index.parent().data(Qt::UserRole).toBool()) {
    // インデックスは親アイテムが非表示なため非表示です
    return true;
}

// 折りたたみ状態をチェック
if (listView->isIndexExpanded(index.parent())) {
    // インデックスは親アイテムが展開されているため表示されています
    return false;
} else {
    // インデックスは親アイテムが折りたたまれているため非表示です
    return true;
}

// 絞り込み条件をチェック
if (listView.hasFilter()) {
    // 絞り込み条件が適用されているため、条件に一致しないインデックスは非表示です
    if (!listView.model()->data(index, QAbstractItemModel::UserRole).isValid()) {
        return true;
    }
}

// 上記のいずれにも該当しないため、インデックスは表示されています
return false;

この方法は、より詳細な制御が必要な場合や、QAbstractItemView::visualRect() 関数が十分な精度を提供しない場合に役立ちます。

選択

どの代替方法を使用するかは、状況によって異なります。

  • モデルインデックスが非表示になる可能性のある要因を個別にチェックする必要がある場合は、個別の要因のチェックを使用する必要があります。
  • アイテムが部分的にしか表示されていない場合や、ビューがスクロールされている場合は、QAbstractItemView::visualRect() 関数を使用する必要があります。
  • アイテムの視覚的な矩形が正確にわかっている場合は、QAbstractItemView::visualRect() 関数を使用するのが最も効率的です。
  • QAbstractItemView::indexAt() 関数を使用して、ビュー内の特定の位置に対応するモデルインデックスを取得できます。
  • QListView::isRowHidden() 関数を使用して、行全体が非表示になっているかどうかを確認することもできます。