QGraphicsView 矢量编辑:移动节点时更新路径 - 正确吗?
QGraphicsView vector edit: update path when moving node – properly?
我正在创建矢量编辑 window。我将元素添加到 QGraphicsScene
并显示它。我还在编写代码,以便在移动节点时,它也会移动底层路径。
但是如何移动通向我尝试移动的点的路径的两个关节?我首先需要将 QPainterPath 分解成子路径(如何?分解成子路径的唯一方法似乎是 toSubpathPolygon 但多边形是一组丢失曲线信息的点......)然后找到我试图改变的点之前的点。我该怎么做?
查看截图:http://imgur.com/a/Q7Yy1
移动节点时,只有一个关节得到更新。
方形节点定义如下:
class OnCurvePointItem(QGraphicsRectItem):
def __init__(self, x, y, width, height, pointX, pointY, pen=None, brush=None, parent=None):
super(OnCurvePointItem, self).__init__(x, y, width, height, parent)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setFlag(QGraphicsItem.ItemIsSelectable)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
if pen is not None: self.setPen(pen)
if brush is not None: self.setBrush(brush)
# Absolute coordinates of the points in the path
self._pointX = pointX
self._pointY = pointY
""" # disabled, trying to use itemChange instead.
def mouseMoveEvent(self, event):
pos = event.pos()
print(pos)
super(OnCurvePointItem, self).mouseMoveEvent(event)
path = self.scene()._outlineItem.path()
path.setElementPositionAt(0, pos.x(), pos.y())
self.scene()._outlineItem.setPath(path)
#self.scene().update()
"""
def itemChange(self, change, value):
#print(change)
if change == QGraphicsItem.ItemPositionHasChanged:
# this is the outline path to mutate, stashed in the scene
path = self.scene()._outlineItem.path()
#for i in range(path.elementCount()):
# elem = path.elementAt(i)
# if elem.isCurveTo(): kind = "curve"
# elif elem.isLineTo(): kind = "line"
# else: kind = "move"
# print("{}: {} {}".format(kind, elem.x, elem.y))
#print()
# self.pos() is relative to the original position in the scene
# hardcoding element 0 till I store index in the item object
path.setElementPositionAt(0, self._pointX+self.pos().x(), self._pointY+self.pos().y())
self.scene()._outlineItem.setPath(path)
return QGraphicsItem.itemChange(self, change, value)
谢谢,我被困在这里了。最后有没有你知道的矢量版的简单 Qt 例子?
我发现了一款名为 Carve 的软件,但代码库相当复杂,我找不到与我在这里所做的事情相关的任何内容……
最后我选择只在每次移动时使用点坐标从头开始创建新的更新路径并在移动发生时调用 QGraphicsPathItem.updatePath()
。
这避免了低级操作的需要,QPainterPath 无论如何都不是专门为之设计的。
我正在创建矢量编辑 window。我将元素添加到 QGraphicsScene
并显示它。我还在编写代码,以便在移动节点时,它也会移动底层路径。
但是如何移动通向我尝试移动的点的路径的两个关节?我首先需要将 QPainterPath 分解成子路径(如何?分解成子路径的唯一方法似乎是 toSubpathPolygon 但多边形是一组丢失曲线信息的点......)然后找到我试图改变的点之前的点。我该怎么做?
查看截图:http://imgur.com/a/Q7Yy1
移动节点时,只有一个关节得到更新。
方形节点定义如下:
class OnCurvePointItem(QGraphicsRectItem):
def __init__(self, x, y, width, height, pointX, pointY, pen=None, brush=None, parent=None):
super(OnCurvePointItem, self).__init__(x, y, width, height, parent)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setFlag(QGraphicsItem.ItemIsSelectable)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
if pen is not None: self.setPen(pen)
if brush is not None: self.setBrush(brush)
# Absolute coordinates of the points in the path
self._pointX = pointX
self._pointY = pointY
""" # disabled, trying to use itemChange instead.
def mouseMoveEvent(self, event):
pos = event.pos()
print(pos)
super(OnCurvePointItem, self).mouseMoveEvent(event)
path = self.scene()._outlineItem.path()
path.setElementPositionAt(0, pos.x(), pos.y())
self.scene()._outlineItem.setPath(path)
#self.scene().update()
"""
def itemChange(self, change, value):
#print(change)
if change == QGraphicsItem.ItemPositionHasChanged:
# this is the outline path to mutate, stashed in the scene
path = self.scene()._outlineItem.path()
#for i in range(path.elementCount()):
# elem = path.elementAt(i)
# if elem.isCurveTo(): kind = "curve"
# elif elem.isLineTo(): kind = "line"
# else: kind = "move"
# print("{}: {} {}".format(kind, elem.x, elem.y))
#print()
# self.pos() is relative to the original position in the scene
# hardcoding element 0 till I store index in the item object
path.setElementPositionAt(0, self._pointX+self.pos().x(), self._pointY+self.pos().y())
self.scene()._outlineItem.setPath(path)
return QGraphicsItem.itemChange(self, change, value)
谢谢,我被困在这里了。最后有没有你知道的矢量版的简单 Qt 例子?
我发现了一款名为 Carve 的软件,但代码库相当复杂,我找不到与我在这里所做的事情相关的任何内容……
最后我选择只在每次移动时使用点坐标从头开始创建新的更新路径并在移动发生时调用 QGraphicsPathItem.updatePath()
。
这避免了低级操作的需要,QPainterPath 无论如何都不是专门为之设计的。