首页 > 解决方案 > QTableView - 如何了解在排序表中选择了哪些项目?

问题描述

我有一个QTableView table. 表的数据由 a 提供QStandardItemModel model,但数据可能按 排序QSortFilterProxyModel。那是:

auto *header = ui.table->horizontalHeader();
// ... some configuration of header
auto *sorted = new QSortFilterProxyModel(window);
QObject::connect(header, &QHeaderView::sortIndicatorChanged, sorted, &QSortFilterProxyModel::sort);
sorted->setSourceModel(model);
ui.table->setModel(sorted);

我在表格中插入的所有元素都是QStandardItem,添加如下:

QStandardItem* item = new QStandardItem("some data");
model->appendRow({item});

现在,当用户选择行时,我想知道QStandardItems选择了哪些行。我试过这样:

QObject::connect(ui.table->selectionModel(), &QItemSelectionModel::selectionChanged, this,
                 [this](const QItemSelection &selected, const QItemSelection &deselected) {
    QModelIndexList selectedIdxs = selected.indexes();
    for(QModelIndex &idx : selectedIdxs) {
        QStandardItem* item = model->item(idx.row());
        //'item' is what I need, do something with it
    }
});

起初它工作得很好。但是,当我对数组进行排序时,我意识到行索引不在它们应该在的位置!如果排序后的元素是第一个,idx.row()似乎返回0,但model对排序一无所知。

所以我的问题是,如何将排序后的索引转换为原始索引?我希望找到一个类似的函数返回一个QStandardItem*like QSortFilterProxyModel::item- 但它不存在。

或者也许有一种更标准的方法,没有任何行索引?

标签: qt

解决方案


如果您考虑 lambda 中的代码...

[this](const QItemSelection &selected, const QItemSelection &deselected)
  {
    QModelIndexList selectedIdxs = selected.indexes();
    for (QModelIndex &idx: selectedIdxs) {
      QStandardItem *item = model->item(idx.row());
      //'item' is what I need, do something with it
    }
  }

问题是 与QModelIndex idx相关联QSortFilterProxyModel而不是QStandardItemModel. 既然如此,就需要利用QSortFilterProxyModel::mapToSource映射idx到对应QModelIndexQStandardItemModel. 假设包含类有一个QSortFilterProxyModel *名为代码的数据成员sorted将变为......

[this](const QItemSelection &selected, const QItemSelection &deselected)
  {
    QModelIndexList selectedIdxs = selected.indexes();
    for (QModelIndex &idx: selectedIdxs) {
      auto source_idx = sorted->mapToSource(idx);
      QStandardItem *item = model->item(source_idx.row());
      //'item' is what I need, do something with it
    }
  }

除上述内容外,您还可以编写一个迭代映射模型索引的函数,直到关联的模型不再是代理模型。像(未经测试)...

QModelIndex map_to_source (QModelIndex index)
{
  const auto *model = index.model();
  for (const auto *pm = dynamic_cast<const QAbstractProxyModel *>(model); pm;
       pm = dynamic_cast<const QAbstractProxyModel *>(model)) {
    index = pm->mapToSource(index);
    model = pm->sourceModel();
  }
  return index;
}

推荐阅读