È stato difficile trovare una buona spiegazione per questo (già alla fine del 2014), e poiché questa domanda richiede esattamente quello che stavo cercando, posterò una trascrizione (da C++ a Python) di ciò che ho trovato in this post.
Il codice è al di sotto, e qui è la logica:
QGrahpicsItem
, QPainterPath
e QPainterPath.Element
sono le classi che stai cercando. Nello specifico, QPainterPath implementa il tipo di funzionalità vettoriale che ci si aspetta da applicazioni come CorelDraw, Adobe Illustrator o Inkscape.
- L'esempio seguente beneficia del valore preesistente
QGraphicsEllipseItem
(per i nodi di rendering) e QGraphicsPathItem
(per il rendering del percorso stesso), che eredita da QGraphicsItem
.
- Il costruttore
Path
itera sopra gli elementi QPainterPath
, creando Node
elementi per ciascuno; Ognuno di loro, a sua volta, invia aggiornamenti all'oggetto Path genitore, che aggiorna la sua proprietà path
di conseguenza.
- Ho trovato molto, molto più facile studiare i documenti Qt4 C++ rispetto ai documenti PyQt piuttosto meno strutturati trovati altrove. Una volta che ti sei abituato a tradurre mentalmente tra C++ e Python, i documenti stessi sono un modo efficace per imparare come usare ogni classe.
#!/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_()
non sappiamo circa il tutorial che si è collegato a. Ricevo un errore di segmentazione ogni volta che chiudo l'applicazione PyQt. – rbaleksandar
Il tutorial è del 2008, quindi alcune cose potrebbero essere cambiate nel frattempo. Segfault-on-close è di solito un segno che qualcosa non va con la durata/configurazione delle classi QT di base (QApplication, QMainWindow etc). Se è possibile eseguire tutorial per la propria versione di PyQt, si dovrebbe essere in grado di incorporare gli elementi necessari per far funzionare QGraphicsScene. – drxzcl
Ho risolto i miei problemi. Ma sì, la versione è vecchia. – rbaleksandar