繁体   English   中英

QTreeView::scrollTo 不工作

[英]QTreeView::scrollTo not working

Qt 4.8

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

使用QTreeView::setSelectionModel(...)正确创建和连接两个类、树视图和模型,一切正常。

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

myTreeView->scrollTo(index);

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

树视图的初始化构造为:

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

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

甚至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);
}

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

当我强制展开所有 1 级项目时,scrollTo 的工作方式与上述相同(调用expandAll就足够了)。

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

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

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

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

ui->treeView->setAutoExpandDelay(0);

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

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

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

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM