Ha sido un dolor encontrar una buena explicación para esto (a partir de finales de 2014), y como esta pregunta pregunta exactamente qué estaba buscando, publicaré una transcripción (de C++ a Python) de lo que encontré en this post.
El código está por debajo, y aquí está la razón de ser:
QGrahpicsItem
, QPainterPath
y QPainterPath.Element
son las clases que está buscando. Específicamente, QPainterPath implementa el tipo de funcionalidad vectorial que espera en aplicaciones como CorelDraw, Adobe Illustrator o Inkscape.
- El ejemplo siguiente se beneficia del
QGraphicsEllipseItem
preexistente (para nodos de representación) y QGraphicsPathItem
(para representar la ruta en sí), que hereda de QGraphicsItem
.
- El constructor
Path
itera sobre los elementos QPainterPath
, creando Node
elementos para cada uno; Cada uno de ellos, a su vez, envía actualizaciones al objeto de ruta padre, que actualiza su propiedad path
en consecuencia.
- Encontré mucho, mucho más fácil estudiar los documentos C++ Qt4 que los documentos PyQt bastante menos estructurados que se encuentran en otros lugares. Una vez que te acostumbras a traducir mentalmente entre C++ y Python, los documentos son una forma poderosa de aprender a usar cada clase.
#!/usr/bin/env python
# coding: utf-8
from PyQt4.QtGui import *
from PyQt4.QtCore import *
rad = 5
class Node(QGraphicsEllipseItem):
def __init__(self, path, index):
super(Node, self).__init__(-rad, -rad, 2*rad, 2*rad)
self.rad = rad
self.path = path
self.index = index
self.setZValue(1)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
self.setBrush(Qt.green)
def itemChange(self, change, value):
if change == QGraphicsItem.ItemPositionChange:
self.path.updateElement(self.index, value.toPointF())
return QGraphicsEllipseItem.itemChange(self, change, value)
class Path(QGraphicsPathItem):
def __init__(self, path, scene):
super(Path, self).__init__(path)
for i in xrange(path.elementCount()):
node = Node(self, i)
node.setPos(QPointF(path.elementAt(i)))
scene.addItem(node)
self.setPen(QPen(Qt.red, 1.75))
def updateElement(self, index, pos):
path.setElementPositionAt(index, pos.x(), pos.y())
self.setPath(path)
if __name__ == "__main__":
app = QApplication([])
path = QPainterPath()
path.moveTo(0,0)
path.cubicTo(-30, 70, 35, 115, 100, 100);
path.lineTo(200, 100);
path.cubicTo(200, 30, 150, -35, 60, -30);
scene = QGraphicsScene()
scene.addItem(Path(path, scene))
view = QGraphicsView(scene)
view.setRenderHint(QPainter.Antialiasing)
view.resize(600, 400)
view.show()
app.exec_()
que no sabemos sobre el tutorial que ha vinculado a. Obtengo un error de segmentación cada vez que cierro la aplicación PyQt. – rbaleksandar
El tutorial es de 2008, por lo que algunas cosas podrían haber cambiado mientras tanto. Segfault-on-close suele ser una señal de que algo anda mal con la duración/configuración de las clases de QT básicas (QApplication, QMainWindow, etc.). Si puede ejecutar tutoriales para su versión de PyQt, debería poder incorporar los elementos necesarios para que QGraphicsScene funcione. – drxzcl
He solucionado mis problemas. Pero sí, la versión es vieja. – rbaleksandar