Commit 9e892ba5 authored by Pierre-Antoine Rouby's avatar Pierre-Antoine Rouby
Browse files

network: Add edge feature and delete node feature.

Showing with 146 additions and 84 deletions
+146 -84
...@@ -191,13 +191,13 @@ class NetworkWindow(ASubWindow): ...@@ -191,13 +191,13 @@ class NetworkWindow(ASubWindow):
def clicked_add(self): def clicked_add(self):
if self.get_push_button_checkable("pushButton_add"): if self.get_push_button_checkable("pushButton_add"):
self.set_push_button_checkable("pushButton_del", False) self.set_push_button_checkable("pushButton_del", False)
self.graph_widget.state = "add" self.graph_widget.state("add")
else: else:
self.graph_widget.state = "move" self.graph_widget.state("move")
def clicked_del(self): def clicked_del(self):
if self.get_push_button_checkable("pushButton_del"): if self.get_push_button_checkable("pushButton_del"):
self.set_push_button_checkable("pushButton_add", False) self.set_push_button_checkable("pushButton_add", False)
self.graph_widget.state = "del" self.graph_widget.state("del")
else: else:
self.graph_widget.state = "move" self.graph_widget.state("move")
...@@ -92,6 +92,8 @@ class NodeItem(QGraphicsItem): ...@@ -92,6 +92,8 @@ class NodeItem(QGraphicsItem):
color = Qt.yellow color = Qt.yellow
if self.graph.selectedNode() == self: if self.graph.selectedNode() == self:
color = Qt.red color = Qt.red
if self.graph.selectedNewEdgeSrcNode() == self:
color = Qt.darkRed
painter.setBrush(QBrush(color)) painter.setBrush(QBrush(color))
painter.drawEllipse(-10, -10, 20, 20) painter.drawEllipse(-10, -10, 20, 20)
...@@ -101,26 +103,17 @@ class NodeItem(QGraphicsItem): ...@@ -101,26 +103,17 @@ class NodeItem(QGraphicsItem):
self.graph.itemMoved() self.graph.itemMoved()
self.graph.nodeChangePosition(value, self) self.graph.nodeChangePosition(value, self)
self.graph.update_edges(self)
return super(NodeItem, self).itemChange(change, value) return super(NodeItem, self).itemChange(change, value)
def mousePressEvent(self, event): def mousePressEvent(self, event):
# Switch selected node # Switch selected node
previous_node = self.graph.selectedNode() if not self.graph.selectedNewEdgeSrcNode():
self.graph.setSelectedNode(self) self.graph.setSelectedNode(self)
# Update previous node
if previous_node:
previous_node.update()
self.update() self.update()
super(NodeItem, self).mousePressEvent(event) super(NodeItem, self).mousePressEvent(event)
# def mouseMoveEvent(self, event):
# self.node.setPos(event.pos().x(), event.pos().y())
# self.update()
# super(NodeItem, self).mousePressEvent(event)
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
self.update() self.update()
super(NodeItem, self).mouseReleaseEvent(event) super(NodeItem, self).mouseReleaseEvent(event)
...@@ -128,79 +121,62 @@ class NodeItem(QGraphicsItem): ...@@ -128,79 +121,62 @@ class NodeItem(QGraphicsItem):
class EdgeItem(QGraphicsItem): class EdgeItem(QGraphicsItem):
Type = QGraphicsItem.UserType + 2 Type = QGraphicsItem.UserType + 2
def __init__(self, edge): def __init__(self, src_node_item, dest_node_item, edge, graph_widget):
super(EdgeItem, self).__init__() super(EdgeItem, self).__init__()
self.arrowSize = 10.0 self.src_node = src_node_item
self.sourcePoint = QPointF() self.dest_node = dest_node_item
self.destPoint = QPointF() self.edge = edge
self.graph = graph_widget
self.src_pos = src_node_item.pos()
self.dest_pos = dest_node_item.pos()
self.setAcceptedMouseButtons(Qt.NoButton) self.setAcceptedMouseButtons(Qt.NoButton)
self.source = edge.node1
self.dest = edge.node2
self.edge = edge
self.adjust() self.adjust()
def type(self): def type(self):
return Edge.Type return Edge.Type
def sourceNode(self): def sourceNode(self):
return self.source return self.src_node.node
def setSourceNode(self, node): def setSourceNode(self, node_item):
self.source = node self.src_node = node_item
self.adjust() self.adjust()
def destNode(self): def destNode(self):
return self.dest return self.dest
def setDestNode(self, node): def setDestNode(self, node_item):
self.dest = node self.dest_node = node_item
self.adjust() self.adjust()
def adjust(self): def adjust(self):
if not self.source or not self.dest:
return
line = QLineF( line = QLineF(
self.mapFromItem(self.source, 0, 0), self.mapFromItem(self.src_node, 0, 0),
self.mapFromItem(self.dest, 0, 0) self.mapFromItem(self.dest_node, 0, 0)
) )
length = line.length() length = line.length()
self.prepareGeometryChange() self.prepareGeometryChange()
if length > 20.0:
edgeOffset = QPointF((line.dx() * 10) / length,
(line.dy() * 10) / length)
self.sourcePoint = line.p1() + edgeOffset
self.destPoint = line.p2() - edgeOffset
else:
self.sourcePoint = line.p1()
self.destPoint = line.p1()
def boundingRect(self): def boundingRect(self):
if not self.source or not self.dest:
return QRectF()
penWidth = 1.0 penWidth = 1.0
extra = (penWidth + self.arrowSize) / 2.0 extra = (penWidth + 5) / 2.0
return QRectF( return QRectF(
self.sourcePoint, self.src_pos,
QSizeF( QSizeF(
self.destPoint.x() - self.sourcePoint.x(), self.dest_pos.x() - self.src_pos.x(),
self.destPoint.y() - self.sourcePoint.y() self.dest_pos.y() - self.src_pos.y()
) )
).normalized().adjusted(-extra, -extra, extra, extra) ).normalized().adjusted(-extra, -extra, extra, extra)
def paint(self, painter, option, widget): def paint(self, painter, option, widget):
if not self.source or not self.dest:
return
# Draw the line itself. # Draw the line itself.
line = QLineF(self.sourcePoint, self.destPoint) line = QLineF(self.src_node.pos(), self.dest_node.pos())
if line.length() == 0.0: if line.length() == 0.0:
return return
...@@ -210,22 +186,22 @@ class EdgeItem(QGraphicsItem): ...@@ -210,22 +186,22 @@ class EdgeItem(QGraphicsItem):
painter.drawLine(line) painter.drawLine(line)
# Draw the arrows if there's enough room. # Draw the arrows if there's enough room.
angle = math.acos(line.dx() / line.length()) # angle = math.acos(line.dx() / line.length())
if line.dy() >= 0: # if line.dy() >= 0:
angle = Edge.TwoPi - angle # angle = Edge.TwoPi - angle
sourceArrowP1 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi / 3) * self.arrowSize, # sourceArrowP1 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi / 3) * self.arrowSize,
math.cos(angle + Edge.Pi / 3) * self.arrowSize) # math.cos(angle + Edge.Pi / 3) * self.arrowSize)
sourceArrowP2 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize, # sourceArrowP2 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize,
math.cos(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize); # math.cos(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize);
destArrowP1 = self.destPoint + QPointF(math.sin(angle - Edge.Pi / 3) * self.arrowSize, # destArrowP1 = self.destPoint + QPointF(math.sin(angle - Edge.Pi / 3) * self.arrowSize,
math.cos(angle - Edge.Pi / 3) * self.arrowSize) # math.cos(angle - Edge.Pi / 3) * self.arrowSize)
destArrowP2 = self.destPoint + QPointF(math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize, # destArrowP2 = self.destPoint + QPointF(math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize,
math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize) # math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize)
painter.setBrush(Qt.black) # painter.setBrush(Qt.black)
painter.drawPolygon(QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2])) # painter.drawPolygon(QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2]))
painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2])) # painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
class GraphWidget(QGraphicsView): class GraphWidget(QGraphicsView):
changeEdge = pyqtSignal(object) changeEdge = pyqtSignal(object)
...@@ -236,9 +212,13 @@ class GraphWidget(QGraphicsView): ...@@ -236,9 +212,13 @@ class GraphWidget(QGraphicsView):
self.timerId = 0 self.timerId = 0
self.parent = parent self.parent = parent
self.state = "move" self._state = "move"
self._selectedNode = None self._selectedNode = None
self._selectedNewEdgeSrcNode = None
self.node_items = []
self.edge_items = []
scene = QGraphicsScene(self) scene = QGraphicsScene(self)
scene.setItemIndexMethod(QGraphicsScene.NoIndex) scene.setItemIndexMethod(QGraphicsScene.NoIndex)
...@@ -259,26 +239,87 @@ class GraphWidget(QGraphicsView): ...@@ -259,26 +239,87 @@ class GraphWidget(QGraphicsView):
self.create_items() self.create_items()
def create_items(self): def create_items(self):
self.node_items = []
self.edge_items = []
for node in self.graph.nodes(): for node in self.graph.nodes():
self.scene().addItem(NodeItem(node, self)) inode = NodeItem(node, self)
self.scene().addItem(inode)
self.node_items.append(inode)
for edge in self.graph.edges():
n1 = list(
filter(
lambda n: n.node.name == edge.node1.name,
self.node_items
)
)
n2 = list(
filter(
lambda n: n.node.name == edge.node2.name,
self.node_items
)
)
# for edge in self.graph.edges(): iedge = EdgeItem(n1[0], n2[0], edge, self)
# scene.addItem(EdgeItem(edge)) self.scene().addItem(iedge)
self.edge_items.append(iedge)
# self.mark = LandMark(1000, 1000, self) # self.mark = LandMark(1000, 1000, self)
# self.scene().addItem(self.mark) # self.scene().addItem(self.mark)
def state(self, status):
self._state = status
def add_node(self, pos): def add_node(self, pos):
node = self.graph.add_node(pos.x(), pos.y()) node = self.graph.add_node(pos.x(), pos.y())
self.scene().addItem(NodeItem(node, self)) inode = NodeItem(node, self)
self.scene().addItem(inode)
self.node_items.append(inode)
self.changeNode.emit(self.sender()) self.changeNode.emit(self.sender())
def del_node(self, node): def del_node(self, node):
self.scene().clear() edges = list(
filter(
lambda ie: ie.edge.node1 == node or ie.edge.node2 == node,
self.edge_items
)
)
for edge in edges:
self.graph.remove_edge(edge.edge.name)
self.graph.remove_node(node.name) self.graph.remove_node(node.name)
self.scene().clear()
self.create_items() self.create_items()
self.changeNode.emit(self.sender()) self.changeNode.emit(self.sender())
self.changeEdge.emit(self.sender())
def add_edge(self, node1, node2):
if node1 == node2:
return
edge = self.graph.add_edge(node1.node, node2.node)
iedge = EdgeItem(node1, node2, edge, self)
self.scene().addItem(iedge)
self.edge_items.append(iedge)
self.setSelectedNode(None)
self.setSelectedNewEdgeSrcNode(None)
self.changeEdge.emit(self.sender())
def update_edges(self, node):
edges = list(
filter(
lambda ie: ie.edge.node1 == node.node or ie.edge.node2 == node.node,
self.edge_items
)
)
for edge in edges:
edge.update()
def itemMoved(self): def itemMoved(self):
if not self.timerId: if not self.timerId:
...@@ -291,7 +332,25 @@ class GraphWidget(QGraphicsView): ...@@ -291,7 +332,25 @@ class GraphWidget(QGraphicsView):
return self._selectedNode return self._selectedNode
def setSelectedNode(self, node): def setSelectedNode(self, node):
previous_node = self._selectedNode
self._selectedNode = node self._selectedNode = node
if node:
self.setSelectedNewEdgeSrcNode(None)
if previous_node:
previous_node.update()
def selectedNewEdgeSrcNode(self):
return self._selectedNewEdgeSrcNode
def setSelectedNewEdgeSrcNode(self, node):
previous_node = self._selectedNewEdgeSrcNode
self._selectedNewEdgeSrcNode = node
if node:
self.setSelectedNode(None)
if previous_node:
previous_node.update()
def keyPressEvent(self, event): def keyPressEvent(self, event):
key = event.key() key = event.key()
...@@ -340,20 +399,23 @@ class GraphWidget(QGraphicsView): ...@@ -340,20 +399,23 @@ class GraphWidget(QGraphicsView):
def mousePressEvent(self, event): def mousePressEvent(self, event):
pos = self.mapToScene(event.pos()) pos = self.mapToScene(event.pos())
if self.state == "move": if self._state == "move":
self.mouse_origin_x = pos.x self.mouse_origin_x = pos.x()
self.mouse_origin_y = pos.y self.mouse_origin_y = pos.y()
elif self.state == "add": elif self._state == "add":
items = self.items(event.pos()) items = self.items(event.pos())
if not items: if not items:
self.add_node(pos) self.add_node(pos)
else: else:
print(f"TODO add edge {items}") nodes = list(filter(lambda i: type(i) == NodeItem, items))
if self.selectedNewEdgeSrcNode() is None:
self.setSelectedNewEdgeSrcNode(nodes[0])
else:
self.add_edge(self.selectedNewEdgeSrcNode(), nodes[0])
elif self.state == "del": elif self._state == "del":
items = self.items(event.pos()) items = self.items(event.pos())
print(f"del: {items}")
if len(items) > 0: if len(items) > 0:
nodes = list(filter(lambda i: type(i) == NodeItem, items)) nodes = list(filter(lambda i: type(i) == NodeItem, items))
if len(nodes) > 0: if len(nodes) > 0:
...@@ -367,6 +429,6 @@ class GraphWidget(QGraphicsView): ...@@ -367,6 +429,6 @@ class GraphWidget(QGraphicsView):
super(GraphWidget, self).mouseReleaseEvent(event) super(GraphWidget, self).mouseReleaseEvent(event)
def mouseMoveEvent(self, event): def mouseMoveEvent(self, event):
if self.state == "move": if self._state == "move":
self.update() self.update()
super(GraphWidget, self).mouseMoveEvent(event) super(GraphWidget, self).mouseMoveEvent(event)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment