使用 QPainterPath 在两点之间绘制直线
Drawing straight line between two points using QPainterPath
我有一个场景,我想使用 QPainterpath 在两点之间画一条线(鼠标按下应该是起点,鼠标释放应该是终点)。
这是我想要的样子的演示。
这是我当前代码的情况。
下面是我试过的代码
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。
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)
感谢@eyllanesc 任何试图使用 QLineF
和 QGraphicsLineItem
实现此目的的人
这是代码。
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
class Scene(QtWidgets.QGraphicsScene):
def __init__(self, *args, **kwargs):
super(Scene, self).__init__(*args, **kwargs)
self.setSceneRect(QtCore.QRectF(0, 0, 500, 500))
self.line = None
self.graphics_line = None
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.line = QtCore.QLineF(self.start_point, self.end_point)
self.graphics_line = QtWidgets.QGraphicsLineItem(self.line)
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():
self.line.setP2(self.end_point)
self.graphics_line.setLine(self.line)
self.addItem(self.graphics_line)
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()
我有一个场景,我想使用 QPainterpath 在两点之间画一条线(鼠标按下应该是起点,鼠标释放应该是终点)。
这是我想要的样子的演示。
这是我当前代码的情况。
下面是我试过的代码
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。
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)
感谢@eyllanesc 任何试图使用 QLineF
和 QGraphicsLineItem
实现此目的的人
这是代码。
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
class Scene(QtWidgets.QGraphicsScene):
def __init__(self, *args, **kwargs):
super(Scene, self).__init__(*args, **kwargs)
self.setSceneRect(QtCore.QRectF(0, 0, 500, 500))
self.line = None
self.graphics_line = None
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.line = QtCore.QLineF(self.start_point, self.end_point)
self.graphics_line = QtWidgets.QGraphicsLineItem(self.line)
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():
self.line.setP2(self.end_point)
self.graphics_line.setLine(self.line)
self.addItem(self.graphics_line)
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()