Using Qt model/view framework to notify QGraphicsItem in a view of user-edit made in another view

我只是一个虾纸丫 提交于 2019-12-20 06:10:00

问题


I am trying to design a multiview application to use Qt's model/view framework so that I can move lots of complex logic out of my QGraphicsItem classes.

As shown in the figure below, the application consists of two (or more) views each containing of an identical series of red vertical guide lines A1 , B1, C1 ... at the same horizontal positions along each view.

I'd like to ensure that when the user drags a guide line one view, say from a point A1 to A_1' as shown in the figure above, all corresponding guide lines in the other views move by the same distance and in the same direction, for example from A2 to A2'. Also it should not be possible to drag one guide line past another i.e. guide lines must retain their relative orders. This is part of the logic that I would like to move out of my GuideLine class, into the model.

I know dragging guide lines triggers QGraphicsItem::itemChange, as shown in the snippet below. What I don't know is how best to

  1. Forward the candidate value to the model for validation (and storage). I am aware that the view is the interface "standard interface for interoperating with models through the signals and slots mechanism". The big problem, as I see it, is that QGraphicsItem::itemChange must immediately return validated value it cannot rely on the asynchronous signal-slot mechanism.
  2. Notify the guide lines in the other views of the change without triggering creating a cascade of notifications, for example where A1 and B1 endlessly notify each other.

-

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

回答1:


QGraphicsScene and QGraphicsView could be seen as a model/view implementation where the scene would be the model and the QGraphicsView would be the view.

Two QGraphicsView can share the same scene and when you modify the scene from one view, the second one will be also updated.

A quick example:

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_())

The rect item is movable and will move in the two views at the same time.



来源:https://stackoverflow.com/questions/56768301/using-qt-model-view-framework-to-notify-qgraphicsitem-in-a-view-of-user-edit-mad

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!