I am currently writing a interactive GUI, the code below inserts nodes and respective edges in a continues manner by mouse events beginning and ending the draw session by making a double click event (based on this post Join QGraphicsItem and QPainter in same GraphicsScene). I want to make the node and edges editable in the sense that after being drawn the user can move around the node position by mouse event as in the following example. how to use QGraphicsView::RubberBandDrag?,
The code
class WindowClass(QMainWindow):
def __init__(self, parent=None):
super(WindowClass, self).__init__(parent)
view = QGraphicsView()
view.setMouseTracking(True)
view.setRenderHint(QPainter.Antialiasing)
scene = SceneClass(self)
view.setScene(scene)
self.setCentralWidget(view)
self.resize(640, 480)
class SceneClass(QGraphicsScene):
def __init__(self, parent=None):
super(SceneClass, self).__init__(QRectF(-1000, -1000, 2000, 2000), parent)
self._edge_item = None
self.pos = None
self.pos_end = None
self.node_start = None
self.node_end = None
def mouseDoubleClickEvent(self, event):
if event.button() == Qt.LeftButton:
"Agregar Nodo"
self.node_start = Node()
self.node_start.setPos(event.scenePos())
self.addItem(self.node_start)
"Agregar Edge"
self._edge_item = Edge()
self._edge_item.src = self.node_start
self.addItem(self._edge_item)
if self.node_end:
self.node_end = None
self.node_start = None
self.node_end = self.node_start
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton and self.node_end:
"Agregar Nodo"
self.node_start = Node()
self.node_start.setPos(event.scenePos())
self.addItem(self.node_start)
self.node_end = self.node_start
"Agregar Edge"
self._edge_item = Edge()
self._edge_item.src = self.node_start
self.addItem(self._edge_item)
def mouseMoveEvent(self, event):
if self._edge_item and self.node_end:
self._edge_item.p1 = event.scenePos()
super(SceneClass, self).mouseMoveEvent(event)
class Node(QGraphicsEllipseItem):
def __init__(self, rect=QRectF(-10, -10, 20, 20), parent=None):
super(Node, self).__init__(rect, parent)
self.edges = []
self.setZValue(1)
self.setBrush(Qt.darkGray)
self.setFlag(QGraphicsItem.ItemIsMovable, True)
self.setFlag(QGraphicsItem.ItemIsSelectable, True)
self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
def addEdge(self, edge):
self.edges.append(edge)
def itemChange(self, change, value):
if change == QGraphicsItem.ItemSelectedChange:
self.setBrush(Qt.green if value else Qt.darkGray)
if change == QGraphicsItem.ItemPositionHasChanged:
for edge in self.edges:
edge.adjust()
return super(Node, self).itemChange(change, value)
class Edge(QGraphicsLineItem):
def __init__(self, parent=None):
super(Edge, self).__init__(parent)
self.setPen(QPen(Qt.red, 3))
self._src = None
self._dst = None
@property
def src(self):
return self._src
@src.setter
def src(self, node):
self._src = node
self._src.addEdge(self)
self.adjust()
@property
def dst(self):
return self._dst
@dst.setter
def dst(self, node):
self._dst = node
self._dst.addEdge(self)
self.adjust()
@property
def p1(self):
return self.line().p1()
@p1.setter
def p1(self, p):
line = self.line()
line.setP1(p)
self.setLine(line)
@property
def p2(self):
return self.line().p2()
@p2.setter
def p2(self, p):
line = self.line()
line.setP2(p)
self.setLine(line)
def adjust(self):
self.prepareGeometryChange()
if self.src:
self.p1 = self.src.pos()
self.p2 = self.src.pos()
if self.dst:
self.p2 = self.dst.pos()
I have tried to initiate by adding a hoover event in the edge class, but after setting to accept hover event and creating a function to instruct action on this event, this function does not trigger.