使用 QPainterPath 在两点之间绘制直线 [英] Drawing straight line between two points using QPainterPath

查看:48
本文介绍了使用 QPainterPath 在两点之间绘制直线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个场景,我想使用 QPainterpath 在两点之间画一条线(鼠标按下应该是起点,鼠标释放应该是终点).

I have a scene where I would like to draw a line between two points(mouse press should be the start point and mouse release as the endpoint) using the QPainterpath.

这是我想要的样子的演示.

Here is a demonstration of how I want it to be.

这是我当前代码的情况.

Here is what's happening with my current code.

下面是我试过的代码

import sys
from PyQt5 import QtWidgets, QtCore, QtGui

class Scene(QtWidgets.QGraphicsScene):

    def __init__(self, *args, **kwargs):
        super(Scene, self).__init__(*args, **kwargs)
        self.point = QtCore.QPointF(0.0, 0.0)

        self.path = QtGui.QPainterPath()

        self.start_point = None
        self.end_point = None

        self.start = False

    def mousePressEvent(self, event):

        self.start_point = event.scenePos()
        self.start = True
        self.path = QtGui.QPainterPath(self.start_point)
        # self.addLine(self.line.setP1(self.start_point))

        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):

        if self.start:
            self.path.lineTo(event.scenePos())
            # self.path.moveTo(event.scenePos())
            self.addPath(self.path, QtGui.QPen(QtCore.Qt.red))

        super(Scene, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):

        if self.start:
            print(self.path)
            self.path.lineTo(event.scenePos())
            # self.path.moveTo(event.scenePos())
            self.addPath(self.path, QtGui.QPen(QtCore.Qt.red))
            self.start = False

        super(Scene, self).mouseReleaseEvent(event)

def main():
    app = QtWidgets.QApplication(sys.argv)

    view = QtWidgets.QGraphicsView()
    view.setRenderHint(QtGui.QPainter.Antialiasing)

    view.setMouseTracking(True)
    scene = Scene()

    view.setScene(scene)
    view.show()
    
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

推荐答案

每次使用 lineTo 都会创建一条新线,起点是最后添加的点,终点是传递给函数的点,因此您可以看到曲线,因为它们是这些线的并集.解决方案是使用 2 个变量来存储起点和终点,并在必要时进行更新,然后使用该信息来更新 QGraphicsPathItem,而不是 QPainterPath.相同的概念可以应用于带有 QLineF 的 QGraphicsLineItem.

Every time lineTo is used then a new line is created where the starting point is the last point added and the end point is the one that is passed to the function, so you see the curves since they are the union of those lines. The solution is to have 2 variables that store the start point and the end point, and be updated when necessary, then use that information to update the QGraphicsPathItem, not the QPainterPath. The same concept can be applied for QGraphicsLineItem with QLineF.

class Scene(QtWidgets.QGraphicsScene):
    def __init__(self, *args, **kwargs):
        super(Scene, self).__init__(*args, **kwargs)

        self.path_item = self.addPath(QtGui.QPainterPath())

        self.start_point = QtCore.QPointF()
        self.end_point = QtCore.QPointF()

    def mousePressEvent(self, event):
        self.start_point = event.scenePos()
        self.end_point = self.start_point
        self.update_path()
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        if event.buttons() & QtCore.Qt.LeftButton:
            self.end_point = event.scenePos()
            self.update_path()
        super(Scene, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        self.end_point = event.scenePos()
        self.update_path()
        super(Scene, self).mouseReleaseEvent(event)

    def update_path(self):
        if not self.start_point.isNull() and not self.end_point.isNull():
            path = QtGui.QPainterPath()
            path.moveTo(self.start_point)
            path.lineTo(self.end_point)
            self.path_item.setPath(path)

这篇关于使用 QPainterPath 在两点之间绘制直线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆