Использование каркаса модели / представления Qt для уведомления QGraphicsItem в представлении редактирования пользователем, выполненном в другом представлении - PullRequest
0 голосов
/ 26 июня 2019

Я пытаюсь спроектировать приложение с несколькими окнами, чтобы использовать каркас модели / представления Qt, чтобы я мог убрать много сложной логики из моих QGraphicsItem классов.

Как показано на рисунке ниже, приложение состоит из двух (или более) видов, каждый из которых содержит одинаковую серию красных вертикальных направляющих линий A1, B1, C1 ... в одинаковых горизонтальных положениях. вдоль каждого вида.

enter image description here

Я бы хотел убедиться, что когда пользователь перетаскивает контрольную линию в одном виде, скажем, из точки A1 в A_1', как показано на рисунке выше, все соответствующие контрольные линии в других видах движутся одинаково расстояние и в том же направлении, например, от A2 до A2'. Также не должно быть возможности провести одну направляющую линию за другой, то есть направляющие должны сохранить свои относительные порядки. Это часть логики, которую я хотел бы перенести из моего класса GuideLine в модель.

Мне известны триггеры перетаскивания направляющих линий QGraphicsItem :: itemChange, как показано во фрагменте ниже. То, что я не знаю, как лучше

  1. Перенаправить значение кандидата в модель для проверки (и хранения). Мне известно, что представление - это интерфейс «стандартный интерфейс для взаимодействия с моделями через механизм сигналов и слотов». Большая проблема, на мой взгляд, заключается в том, что QGraphicsItem::itemChange должен немедленно возвращать проверенное значение, которое он не может использовать для асинхронного механизма слотов сигналов.
  2. Уведомлять направляющие линии в других видах об изменениях, не вызывая создания каскада уведомлений, например, когда A1 и B1 бесконечно уведомляют друг друга.

-

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 Ответ

0 голосов
/ 26 июня 2019

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

Прямоугольный элемент является подвижным и перемещается в двух видах одновременно.

...