【问题标题】:Modelling self-modifying data / wrapper models in Qt在 Qt 中对自修改数据/包装器模型进行建模
【发布时间】:2013-10-05 15:05:33
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

    2. 模型调用beginRemoveRows()

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

    4. 模型调用endRemoveRows()

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

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

    【讨论】:

    • 抱歉回复晚了。谢谢你的澄清。我目前的解决方案禁止修改底层 SG 直接,因此所有视图都必须通过模型对其进行修改。所以修改的唯一方向就是view -> model -> SG,完全没有问题。这似乎是最简洁的设计。
    • 你所描述的正是我上面写的,实际上是一个人应该如何做事。 SG 是一个实现细节。派生自QAbstractItemModel(或其子类)的模型是视图与之交互的对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    相关资源
    最近更新 更多