1

在 Qt 中,我正在编写自己的树模型(通过子类QAbstractItemModel化),它围绕现有的数据结构。应该可以在内部(而不是通过模型)以及通过模型(因此视图可以更改它)更新数据结构。为了更好地想象它:它是一个场景图,应该可以使用场景视图(无需通过 Qt 模型)进行编辑,也可以使用大纲(QTreeView它使用 Qt 模型作为场景图周围的代理)进行编辑。

为了避免混淆,我们应该考虑两种不同的场景(在下面,我以“删除”操作为例):

  1. 用户使用 Qt 视图删除一个节点。视图想要从模型中删除一行,使用QAbstractItemModel::removeRow. 这应该反过来从底层数据结构场景图中删除相应的节点。 场景 1 中的调用

  2. 用户使用场景视图移除节点。场景视图想要从场景图中移除一个节点。环绕场景图的模型会收到通知,然后想要通知连接的视图一行刚刚被删除。 场景 2 中的调用

虽然我认为我知道如何实现 1.,但我不知道如何实现 2 中的通知部分。有信号QAbstractItemModel::rowsAboutToBeRemoved()以及rowsRemoved()听起来像他们是我的朋友。但它们是私有信号(他们在标头源代码中说:“只能由 QAbstractItemModel 发出”)。还有beginRemoveRows()endRemoveRows()但根据他们的文档,当从视图发生更新时,应该调用它们,即当removeRow被调用时。此外,当我尝试使用它们时,视图完全被搞砸了。

根据文档,模型类似乎并不打算对自修改数据进行建模。让我们以文件系统为例。当使用可以检测目录更改的文件系统监视时,模型应该通知视图以便可以实时显示目录中的更改,即使视图没有用于修改文件系统。Qt 中甚至可以使用这样的模型吗?

4

1 回答 1

1

你读错了。当模型即将开始改变其“几何”时,它必须向用户发出信号。因此,无论从模型中删除行是什么,它都必须告诉外界它发生了。当视图从模型中删除行时的事件顺序如下:

  1. 视图调用model->removeRows().

  2. 模型调用beginRemoveRows()

  3. 该模型实际上从内部数据中删除了行。

  4. 该模型调用endRemoveRows().

如果你实现了一些其他的接口来删除行而不调用model->removeRows(),你必须做同样的事情。不管是视图还是其他从模型中删除行的代码,模型的行为都必须相同,否则什么都不会起作用。

您可以构建一个插入到 SceneGraph 和模型之间的适配器类。它应该持有指向场景图和模型的指针,并转换两者之间的操作。

于 2013-10-05T19:57:13.287 回答