【问题标题】:Update of QTreeView without changing selection在不更改选择的情况下更新 QTreeView
【发布时间】:2018-07-23 08:39:09
【问题描述】:

我有一个模型,它通过某个 SQL 查询从数据库中的表中检索数据,并在 QTreeView 中显示这些项目。特点是:

  • 数据来自表,但具有底层树结构(某些行是父行,其下方的行是子行)
  • 此树结构显示在 QTreeView 中
  • 子项在 QTreeView 中是可选的(不是父项)
  • 数据库中的表不断更新
  • 在更新中,可以将子级添加到任何现有父级中
  • 定期(使用 QTimer)QTreeView 使用表的内容进行更新

由于子项随时添加到任何父项,更新 QTreeView 时第一个愚蠢的方法是将其全部清除,并以父项或子项的形式再次将所有行附加到 QTreeView。这是一个 0 阶的近似值,它确实是非常低效的。尤其会出现以下问题:

  1. 任何现有的选择都消失了
  2. 显示其子级的任何展开的父级都将折叠(除非 ExpandAll 处于活动状态)
  3. 视图被重置以显示第一行。

这个问题的最佳解决方案是什么?我的意思是,我将尝试的第一个解决方案不是清除 QTreeView,而是解析表中所有返回的行,并检查每个行是否存在 QTreeView 中的相应项,如果不存在则添加。但我想知道是否有一个最棘手的解决方案来使用 QTreeView 将数据库中的给定表(我知道 QTableView 存在这种情况,但是树结构消失了)。

【问题讨论】:

  • 你知道应该更新哪个节点吗?换句话说,您是否有关于应该添加到树中的每个特定项目的信息?
  • 检索到的第一列(未显示在 QTreeView 中)包含一个索引值,它应该告诉我这个项目是父项还是子项,查看当前 QTreeView 我应该看看这是否是是否已经在视图中。
  • 我相信,如果您使用beginInsertRowsendInsertRows 正确插入新项目,树视图选择和节点状态将保留为更新树之前的状态。
  • 好的,我会尽力告诉你的,谢谢!
  • 最后,在仔细分析从数据库中检索到哪些数据之后,只询问以前未获得的记录,并使用几个内部 ID 对数据进行分组和排序,并且还仔细使用了 beginInsertRows() 和 endInsertRows(),接收模型更新的 QTreeView 中的当前位置和选择被保留,并且视图中的项目被添加并且对用户透明地更新视图。顺便说一句,就我而言,在每次更新后重新应用排序状态也很重要。谢谢大家!

标签: c++ sql qt qtreeview


【解决方案1】:

我想这是自我回答的情况。

如我所料,在仔细分析了从数据库中检索到哪些数据之后,我不得不对检索代码进行以下“升级”:

  • 我检索了两个标识符以及我想在视图中显示的字段,一个用于对行进行分组,一个用于将项目分类到组中
  • 我还从数据库中的表中检索内部记录 ID(一个递增的整数),以便在下一次检索时仅请求新记录。

在模型人口代码中,我添加了以下内容:

  • 我首先扫描可能属于模型中现有组的初始记录
  • 在扫描过程中,当我到达模型中的最后一个组时,这意味着检索到的其余记录属于新组(请记住,检索记录是按排序的,以便一起检索属于同一组的项目)
  • 然后开始创建组并向每个组添加项目,直到我们使用检索到的所有记录。

最后,很重要的一点:

  • 在模型中插入新项目之前和之后使用beginInsertRows()endInsertRows()
  • 捕获视图的排序状态(使用sortIndicatorSection()sortIndicatorOrder())并在更新模型后重新应用此排序状态(使用sortByColumn()

这样做会保留接收模型更新的 QTreeView 中的当前位置和选择,并添加视图中的项目并为用户透明地更新视图。

【讨论】:

    【解决方案2】:

    This thread 提到了一种通用方法,但这可能很快就会变得棘手,但我不确定如果底层模型不断变化(即QModelIndex 变得无效),这将如何工作。

    最坏的情况是您必须编写自己的机制来记住在更新然后重新应用之前的选择。

    我假设您使用了一些 model/view 实现?如果上面提到的示例不适合您,您可以通过安全的选择处理来增强您的模型。

    【讨论】:

    • 我使用模型/视图实现,是的。模型中的第一列是一种索引,它特别告诉我是否应该添加新的父级。我会尝试这种方法,但恐怕我会面临这些QModelIndex 失效。我还在其他地方看到了关于将每个项目的内部数据设置为 selected 标志,并据此更改视图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    相关资源
    最近更新 更多