【问题标题】:Qt TreeView problem when used with sort model与排序模型一起使用时的 Qt TreeView 问题
【发布时间】:2018-12-18 19:43:47
【问题描述】:

我有一个问题,到目前为止我没有找到解决方案,实际上问题是QModelIndex 我们必须何时调用beginInsertColumns 和类似的函数。 我的示例是此处的标准 Qt 示例: http://doc.qt.io/qt-5/qtwidgets-itemviews-editabletreemodel-example.html

它也随每个 qt 安装一起提供,例如C:\Qt\Qt5.12.0\Examples\Qt-5.12.0\widgets\itemviews\editabletreemodel

刚执行时,它工作正常,但现在让我们插入一个QSortFilterProxyModel,只是为了使它可排序。我们将 MainWindow c'tor 更改为

...
QFile file(":/default.txt");
file.open(QIODevice::ReadOnly);
TreeModel *model = new TreeModel(headers, file.readAll());
file.close();

QSortFilterProxyModel* sort = new QSortFilterProxyModel( this );
sort->setSourceModel( model );

view->setModel( sort );
...

现在执行示例,展开一两个根节点并选择菜单项“插入列”,您将看到,只有根节点有一个新列,它们的所有子节点都没有新列。它在没有代理的情况下工作。现在我的问题是,我是否必须为每个有孩子的QModelIndex 发出beginInsertColumns

我该如何解决这个问题? 请注意,这不仅是 qt 5.12 的问题,也是许多早期版本的问题。

【问题讨论】:

  • 我只是快速浏览了一下示例代码,但它似乎总是通过view->model() 访问模型。如果是这样,我怀疑您实际上可能正在尝试向代理添加一列,而不是 TreeModel。否则这真的需要minimal reproducible example
  • 当然可以,但是由于排序代理是代理,所以没关系。无论如何,直接使用TreeModel时问题仍然存在。
  • 尝试将您的模型运行到 QAbstractItemModelTester 中。
  • 我做到了,一切都很好。而且模型是标准的qt例子,应该是正确的。
  • Now my question, do i have to emit beginInsertColumns for every QModelIndex that has children?。看这张图:doc.qt.io/qt-5/images/modelview-models.png,Qt 中的模型基本上是一棵二维表树。 (为了约定,树模型仅在第一列下展开)。但无论如何,如果您需要在子节点中添加 2 列,则还需要在父节点中插入开始/结束列。

标签: c++ qt qt5


【解决方案1】:

我一直在使用 QSortFilterProxyModel 时遇到问题,据我所知,它们通常与源模型之间的索引映射有关。

我设法使用 QSortFilterProxyModel::invalidate() 方法解决了这个问题,该方法将重置映射,而不会破坏视图的当前状态。

修改MainWindow::insertColumn如下:

bool MainWindow::insertColumn()
{
    QAbstractItemModel *model = view->model();
    int column = view->selectionModel()->currentIndex().column();

    bool changed = false;
    // Insert a column in the parent item.
    QSortFilterProxyModel* sfpm = qobject_cast<QSortFilterProxyModel*>(model);
    if (sfpm)
    {
        changed = sfpm->insertColumn(column + 1);
        if (changed)
            sfpm->setHeaderData(column + 1, Qt::Horizontal, QVariant("[No header]"), Qt::EditRole);

        sfpm->invalidate();
    }

    updateActions();
    return changed;
}

这不是最佳解决方案,我不知道是否有更好的方法,但对我有用。

【讨论】:

  • 当然,这是一个解决方案。但是在我的实际应用程序中,树模型会因外部信号而发生变化,并且模型不应该知道以下排序代理。当然,有一些解决方法,但如果能正常工作那就太好了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多