QGraphicsView将一行连接到另一个QGraphicsSceneItem

时间:2017-01-28 14:56:10

标签: python pyqt

我正在扩展Qt的QGraphicsView框架以创建交互式形状构建器。当您单击并拖动时,它会创建一个带有贝塞尔手柄的控制点来实现其曲线(与let中的路径相同,即Photoshop)。

我有控制点的单独项目,以及两个贝塞尔手柄点。我正在努力想方设法显示贝塞尔手柄的线段,从一个贝塞尔点到控制点。

顶部直线贝塞尔线的示例: 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)

或者是为线本身创建项目的更好方法?欣赏任何见解!

1 个答案:

答案 0 :(得分: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)