【问题标题】:The easiest way to make a "tracking" item selection in TreeView?在 TreeView 中进行“跟踪”项目选择的最简单方法是什么?
【发布时间】:2014-06-26 20:32:16
【问题描述】:

好的,所以我设置了一个QTreeView 和一个从QAbstractItemModel 子类化的模型。到目前为止一切顺利。

模型的数据每隔固定时间间隔更新一次,例如两秒。假设为简单起见,这些项目只是短整数,并且没有层次结构。所有项目都是独一无二的

t=0:

497
1739
18
125
19

用户选择项目18

t=1:

497
1739
[18]
125
19

t=2,物品列表更新变化!

497
18
[1739]
125

例如,173918 现在交换了,最后一个 19 消失了。
哎呀! 1739 现在被选中,这似乎是合法的:用户选择了第三个项目,并且即使在更新后仍然被选中。

我希望现在的问题很明显:我需要选择来“跟踪”究竟选择了什么项目。使用项目本身的一些内部 id。因此,如果新列表包含与先前选择的项具有相同 id 的项,它将被选中。

我可以在更新时自己更改选择,或使用insertRowremoveRow,但我不知道列表中究竟发生了什么变化(173918 已交换),我刚刚收到一个新的整数列表。

我看过 QItemSelectionModel,虽然 Qt 文档说

QItemSelectionModel 类跟踪视图的选定项。

,它看起来不像我需要的。我认为这是我需要子类化的另一个代理模型,但事实并非如此。

接下来我认为我的模型是编写跟踪选择的代码的正确位置,但我又失败了:模型无法检索视图的选择模型 (view->selectionModel()),因为它无法访问视图。

我最终可能会在我的模型中编写一些信号和槽,以便模型外部的代码可以更新选择,加上模型外部连接到视图的 selectionModel 的槽来更新存储在模型中的当前选定项目的 id等,但在写这些东西之前,我想问问是否已经有一些我不知道的练习。

解释所有这些东西的文档和文章太少了,我自己也找不到上述问题的答案。

谢谢!

【问题讨论】:

    标签: c++ qt model-view-controller qt4 selection


    【解决方案1】:

    最好检测何时从模型中添加/移动/删除项目并发出相应的信号,但这会很复杂,您可能不需要如此复杂的功能。

    假设您对单选感兴趣,您可以很简单地做到这一点。当当前选择更改时,只需存储所选值。 当您收到模型已更改的通知时,只需找到项目的新位置并更新选择即可。

    void onCurrentSelectionChange(const QModelIndex & index) { // slot
        selectedValue = index->data(); // update field: QVariant selectedValue
    }
    
    void onModelReset() { // slot connected to signal where model reports that it was changed
        QModelIndex newSelection = yourModel->findIndexOfValue(selectedValue); // you have to provide such method in your moel
        emit newSelection(newSelection); // signal connected to setCurrentIndex slot of QTreeView or selection model
    }
    

    如果你想处理更复杂的选择,那就更麻烦了。

    【讨论】:

      【解决方案2】:

      我认为您自己提供了答案。您可以为每个项目使用唯一的内部 id:

      template<typename T>
      class Item {
      public:
          Item(int id, T data);
          // Access methods here.
      private:
          int id;
          T data;
      };
      

      然后,每次您从计时器收到timeout 时,您都可以更新您的项目选择列表:

      vector<int> selection;
      for (int &index: treeview->selectionModel()->selectedIndexes()){
          selection.push_back(model[index].id);  // This assumes you implement [] operator for your model.
      }
      
      // Do modify list.
      
      // and the using QModelSelection select again every item which id is in 
      // `selection`
      

      这样您就可以“跟踪”所选项目。

      取决于项目值不是一个好主意,因为这将解决方案限制为包含唯一值的模型。使用selectionChanged 信号也不是一个好主意,因为它会由用户触发,但在您以编程方式更改选择时也会由您触发,这会产生无限循环。

      【讨论】:

      • 问题被标记为“C++”。
      • 好的,答案翻译成 C++。
      猜你喜欢
      • 2019-05-13
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多