2017-01-28 21 views
0

Я расширяю рамки Qt QGraphicsView Qt для создания интерактивного построителя фигур. Когда вы нажимаете и перетаскиваете, он создает контрольную точку с дескриптором bezier для выполнения своей кривой (так же, как и пути, скажем, Photoshop).QGraphicsView подключает линию к другому QGraphicsSceneItem

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

Пример прямой линии Безье на вершине: Want to create that line!

Какой самый лучший подход, чтобы отобразить это? Я попытался переопределить paintEvent, который отлично рисует линию, но некоторые части представления не поняли и немного напуганы.

Вот что код выглядел так:

def paintEvent(self, event): 

    painter = QtGui.QPainter(self.viewport()) 

    if self.points: 
     painter.begin(self) 
     painter.fillRect(self.viewport().rect(), QtGui.QBrush(QtGui.QColor(50, 50, 50))) 
     for point in self.points: 
      if point.point_type != ControlPoint.Bezier: 
       continue 

      painter.drawLine(point.handle_1.pos().x(), point.handle_1.pos().y(), 
          point.handle_2.pos().x(), point.handle_2.pos().y()); 
     painter.end() 

    QtGui.QGraphicsView.paintEvent(self, event) 

Или это лучший подход, чтобы создать элемент для самой линии? Цените любое понимание!

ответ

0

Вот мое текущее решение. Я подклассифицирую QGraphicsScene.drawForeground, чтобы нарисовать все линии между любыми точками безье. Единственное плохо, что я должен обновить весь видовой экран, иначе он не очистит все предыдущие розыгрыши. Так что это может застрелить меня в ногу позже с точки зрения производительности.

Кроме этого, он отлично работает, даже когда вы перемещаете точки вокруг, я получаю хороший сегмент, следующий за ним.

def drawForeground(self, painter, rect): 
    view = self.views()[0] 

    # Forces whole view to update instead of partial. 
    view.viewport().update() 

    painter.begin(view) 

    if view.points: 
     pen = QtGui.QPen(QtCore.Qt.white, 1, QtCore.Qt.DashLine) 
     painter.setPen(pen) 

     for point in view.points: 
      if point.point_type != ControlPoint.Bezier: 
       continue 

      painter.drawLine(point.handle_1.pos().x(), point.handle_1.pos().y(), 
          point.handle_2.pos().x(), point.handle_2.pos().y()); 
    painter.end() 

    return QtGui.QGraphicsScene.drawBackground(self, painter, rect)