2017-01-28 4 views
0

QtのQGraphicsViewフレームワークを拡張して、インタラクティブなシェイダービルダを作成します。クリックしてドラッグすると、ベジェハンドルでコントロールポイントが作成され、曲線になります(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) 
関連する問題