4

Qt 4.8

我有一个QTreeView带有关联基础类的QAbstractItemModel基础类。如果我用新信息重新加载模型,我想将树展开/滚动到上一个选定的项目。

使用正常工作的一切都正确创建和连接了类、树视图和模型QTreeView::setSelectionModel(...)

重新加载模型后,我得到了前一个选定项目的有效索引,然后我滚动到它:

myTreeView->scrollTo(index);

但树没有展开。但是,如果我手动展开树,则该项目确实被选中。

树视图的初始化构造为:

header()->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
header()->setStretchLastSection(false);
header()->setResizeMode(0, QHeaderView::ResizeToContents);

关于将树扩展到选择的任何想法?

4

6 回答 6

4

甚至QTreeView::scrollTo文件说:

Scroll the contents of the tree view until the given model item index is 
visible. The hint parameter specifies more precisely where the item should 
be located after the operation. If any of the parents of the model item 
are collapsed, they will be expanded to ensure that the model item is visible.

这不是真的(我认为)

如果解决了手动扩展所有先前树级别的问题:

// This slot is invoqued from model using last selected item
void MyTreeWidget::ItemSelectedManually(const QModelIndex & ar_index)
{
    std::vector<std::pair<int, int> > indexes;

    // first of all, I save all item "offsets" relative to its parent

    QModelIndex indexAbobe = ar_index.parent();
    while (indexAbobe.isValid())
    {
        indexes.push_back(std::make_pair(indexAbobe.row(), indexAbobe.column()));
        indexAbobe = indexAbobe.parent();
    }

    // now, select actual selection model

    auto model = _viewer.selectionModel()->model();

    // get root item

    QModelIndex index = model->index(0, 0, QModelIndex());
    if (index.isValid())
    {
        // now, expand all items below

        for (auto it = indexes.rbegin(); it != indexes.rend() && index.isValid(); ++it)
        {
            auto row = (*it).first;
            auto colum = (*it).second;

            _viewer.setExpanded(index, true);

            // and get a new item relative to parent
            index = model->index(row, colum, index);
        }
    }

    // finally, scroll to real item, after expanding everything above.
    _viewer.scrollTo(ar_index);
}
于 2013-07-09T11:43:23.083 回答
3

我刚刚处理了类似的情况,通过 setModelIndex 设置模型索引(内部以 scrollTo 结尾)对我的一个模型工作正常,但对另一个模型却很糟糕。

当我强行扩展所有 1 级项目时,scrollTo 就像上面描述的那样工作(调用expandAll就足够了)。

原因是我的模型类中的一个错误:

QModelIndex MyBadModel::parent(const QModelIndex& index) const

当我解决这个问题时,那里的事情也变得正常了。该错误是internalId父模型索引与“从其他方向”计算相同模型索引(对于父模型)时不同,因此在此模型索引(由parent方法返回)无法在视觉列表中找到指数。

于 2014-01-29T15:02:52.133 回答
1

一切很简单。只需将 autoExpandDelay 属性从 -1 更改为 0(例如)。

ui->treeView->setAutoExpandDelay(0);
于 2015-05-19T19:27:24.287 回答
0

QTreeView::scrollTo应适当扩展层次结构。

当模型更新时,您的QModelIndex对象可能会失效(并且可能仍然选择正确的行,因为行信息仍然有效,尽管父系不是,不要问我这些内部是如何工作的)。从QModelIndex 文档中:

注意:模型索引应立即使用,然后丢弃。在调用更改模型结构或删除项目的模型函数后,您不应依赖索引保持有效。如果您需要随着时间的推移保留模型索引,请使用QPersistentModelIndex

您当然可以查看该QPersistentModelIndex对象,但就像它在其文档中所说的那样:

在使用持久模型索引之前检查它们是否有效是一种很好的做法。

否则,您始终可以在模型刷新后再次查询该项目。

于 2013-07-08T15:35:57.383 回答
0

您可能scrollTo在树视图完成对当前索引的更改做出反应以及哪些索引被展开/折叠之前调用。一种可能的解决方案可能是通过将调用scrollTo连接到单次计时器来延迟调用,如下所示:

QTimer::singleShot(0, [this]{scrollTo(index);});

使用计时器将延迟调用,直到将控制权传递回事件队列。

于 2022-01-10T18:19:06.113 回答
0

最近我在同样的问题上苦苦挣扎。这很可能是您的模型类实现中的错误。在我的情况下,row() 方法(应该返回其父级下的索引的索引)没有正确实现。可悲的是 QT 并没有抱怨,甚至选择了索引(如果你手动展开你会注意到)。因此,只需浏览模型代码并寻找 row() 和 parent() 方法等中的错误。

于 2020-10-30T21:05:07.680 回答