【问题标题】:Using Qt model/view framework to notify QGraphicsItem in a view of user-edit made in another view使用 Qt 模型/视图框架在另一个视图中进行用户编辑的视图中通知 QGraphicsItem
【发布时间】:2019-11-08 03:12:23
【问题描述】:

我正在尝试设计一个多视图应用程序以使用 Qt 的模型/视图框架,以便我可以将大量复杂逻辑从我的 QGraphicsItem 类中移出。

如下图所示,应用程序由两个(或多个)视图组成,每个视图都包含相同系列的红色垂直引导线A1B1C1 ... 在相同的水平位置沿着每个视图。

我想确保当用户在一个视图中拖动引导线时,例如从点A1A_1',如上图所示,其他视图中所有对应的引导线都移动相同距离和同一方向,例如从A2A2'。此外,不应将一条引导线拖过另一条引导线,即引导线必须保持其相对顺序。这是我想从 GuideLine 类移到模型中的部分逻辑。

我知道拖动引导线会触发QGraphicsItem::itemChange,如下面的sn-p所示。我不知道怎么做最好

  1. 将候选值转发到模型进行验证(和存储)。我知道视图是接口“通过信号和插槽机制与模型互操作的标准接口”。在我看来,最大的问题是QGraphicsItem::itemChange 必须立即返回验证值,它不能依赖异步信号槽机制。
  2. 在不触发创建级联通知的情况下通知其他视图中的指南更改,例如A1B1 无休止地相互通知。

-

class GuideLine( QtGui.QGraphicsLineItem ):
    ...
    # Called when item is about to change to value
    def itemChange( self , change , value ):
        # TODO 
        #  1. validate value in model
        #  2. if change is valid notify peers in other views
        pass

【问题讨论】:

    标签: pyside qgraphicsitem model-view


    【解决方案1】:

    QGraphicsScene 和 QGraphicsView 可以看作是模型/视图实现,其中场景是模型,QGraphicsView 是视图。

    两个 QGraphicsView 可以共享同一个场景,当你从一个视图修改场景时,第二个也会更新。

    一个简单的例子:

    if __name__ == "__main__":
    
        app = QApplication([])
        scene = QGraphicsScene(0, 0, 1000, 1000)
        view1 = QGraphicsView()
        view2 = QGraphicsView()
    
        item = QGraphicsRectItem(QRectF(0, 0, 40, 40))
        item.setFlag(QGraphicsItem.ItemIsMovable)
        scene.addItem(item)
    
        view1.setScene(scene)
        view2.setScene(scene)
    
        w = QWidget()
        layout = QVBoxLayout(w)
        layout.addWidget(view1)
        layout.addWidget(view2)
        w.show()
    
        sys.exit(app.exec_())
    

    矩形项是可移动的,会同时在两个视图中移动。

    【讨论】:

    • 不幸的是,共享场景可能不起作用,因为视图需要垂直拉伸到不同的高度。此外,每个视图除了引导线之外还有其他 QGraphicsItems,因此可能需要多个场景。
    • QGraphicsView 可以独立于场景处理它们的高度,您可以隐藏与视图相关的一些项目。所以,我仍然认为你应该只使用一个场景。但是,如果您想使用两个场景,最简单的方法是使用自定义 QGraphicsItem 和自定义模型来处理它们的位置和几何形状,而不是尝试将它们相互连接。
    • 正如我所说,指南更新了视图中的其他 QGraphicsItems。事实上,一般来说,拖动一个QGraphicsItems 会影响剩余项目的一个子集。 (我没有提到这一点是因为我想让问题保持简单。我认为答案更新指南将适用于其他图形项。)也就是说,这种方法不会导致 @ 中有大量逻辑987654325@s课?
    猜你喜欢
    • 1970-01-01
    • 2011-03-12
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 2021-05-14
    • 1970-01-01
    • 2012-04-15
    相关资源
    最近更新 更多