def user_trace(graph: pgv.AGraph, quantities: List[Quantity]): def request_value(quantity: Quantity) -> Tuple[str,str]: print('Values for {}:'.format(quantity.name)) mag = input("Magnitude? (out of [{}])\n".format(','.join(quantity.magnitude._member_names_))) if mag == "": mag = quantity.magnitude._member_names_[0] drv = input("Derivative? (out of [{}])\n".format(','.join(quantity.derivative._member_names_))) if drv == "": drv = quantity.derivative._member_names_[1] return (mag,drv) print('Enter start node for trace:') start = str(tuple(request_value(q) for q in quantities)) if not graph.has_node(start): print('START NODE NOT IN GRAPH') return print('\n\nEnter end node for trace:') end = str(tuple(request_value(q) for q in quantities)) if not graph.has_node(end): print('END NODE NOT IN GRAPH') return shgraph = trace(graph, start, end) shgraph.draw('trace.pdf', prog='dot')
class UiGraphio(QMainWindow): """ Main window for application """ def __init__(self): """ Constructor """ QMainWindow.__init__(self) self.ui = graphio.Ui_MainWindow() self.ui.setupUi(self) self.scene_graph = QGraphicsScene() self.ui.graphicsView.setScene(self.scene_graph) self.ui.graphicsView.update() self.graph = AGraph(strict=True, directed=True) self.graph.layout(prog='dot') ##################################################### # View update ##################################################### def update_adj_matrix(self): count = self.graph.number_of_nodes() self.ui.tw_adjmatrix.setRowCount(count) self.ui.tw_adjmatrix.setColumnCount(count) self.ui.tw_adjmatrix.setHorizontalHeaderLabels(self.graph.nodes()) self.ui.tw_adjmatrix.setVerticalHeaderLabels(self.graph.nodes()) for (i, u) in enumerate(self.graph.nodes()): for (j, v) in enumerate(self.graph.nodes_iter()): if self.graph.has_edge(u, v): self.ui.tw_adjmatrix.setItem( i, j, QTableWidgetItem( self.graph.get_edge(u, v).attr['label'])) else: self.ui.tw_adjmatrix.setItem(i, j, QTableWidgetItem(str(0))) def update_matrix_incidence(self): nodes = self.graph.nodes() edges = self.graph.edges() self.ui.tw_incmatrix.setRowCount(len(nodes)) self.ui.tw_incmatrix.setColumnCount(len(edges)) self.ui.tw_incmatrix.setHorizontalHeaderLabels( [str(node) for node in self.graph.edges()]) self.ui.tw_incmatrix.setVerticalHeaderLabels(self.graph.nodes()) for (i, u) in enumerate(nodes): for (j, edg) in enumerate(edges): value = 0 if (u == edg[0]): value = 1 elif (u == edg[1]): value = -1 self.ui.tw_incmatrix.setItem(i, j, QTableWidgetItem(str(value))) def update_list_edges(self): edges = self.graph.edges() self.ui.tw_edges.setRowCount(len(edges)) for (i, edge) in enumerate(edges): self.ui.tw_edges.setItem(i, 0, QTableWidgetItem(edge[0])) self.ui.tw_edges.setItem(i, 1, QTableWidgetItem(edge[1])) def update_adj_list(self): nodes = self.graph.nodes() self.ui.tw_adjlist.setRowCount(self.graph.number_of_nodes()) self.ui.tw_adjlist.setVerticalHeaderLabels(nodes) for (i, node) in enumerate(nodes): value = '' for adj in self.graph.out_edges(node): value += adj[1] + ', ' self.ui.tw_adjlist.setItem(i, 0, QTableWidgetItem(value[:-2])) ##################################################### # Reset editors ##################################################### def add_cb_item(self, label): n = self.ui.cb_nodes.count() i = 0 while i < n: itext = self.ui.cb_nodes.itemText(i) if label == itext: return elif label < itext: break i += 1 # insert item to lists self.ui.cb_nodes.insertItem(i, label) self.ui.cb_starting_node.insertItem(i, label) self.ui.cb_ending_node.insertItem(i, label) @pyqtSlot(bool, name='on_bt_add_node_clicked') @pyqtSlot(bool, name='on_bt_del_node_clicked') @pyqtSlot(bool, name='on_bt_add_edge_clicked') @pyqtSlot(bool, name='on_bt_del_edge_clicked') def reset_editors(self): self.ui.cb_nodes.clearEditText() self.ui.cb_starting_node.clearEditText() self.ui.cb_ending_node.clearEditText() self.ui.sb_weight_edge.setMinimum() def redraw(self): self.graph.draw('graph', 'png', 'dot') self.scene_graph.clear() self.scene_graph.addItem(QGraphicsPixmapItem(QPixmap('graph'))) self.ui.graphicsView.update() ##################################################### # Buttons actions ##################################################### @pyqtSlot() def on_bt_add_node_clicked(self): """ Slot when click on Add node button """ label = self.ui.cb_nodes.currentText() if not self.graph.has_node(label): self.add_cb_item(label) self.graph.add_node(label) self.redraw() @pyqtSlot() def on_bt_del_node_clicked(self): """ Slot when click on Delete node button """ index = self.ui.cb_nodes.currentIndex() label = self.ui.cb_nodes.currentText() if index > -1 and self.graph.has_node(label): self.graph.remove_node(label) self.redraw() self.ui.cb_nodes.removeItem(index) self.ui.cb_starting_node.removeItem(index) self.ui.cb_ending_node.removeItem(index) @pyqtSlot() def on_bt_add_edge_clicked(self): """ Slot when click on Add branch button """ start = self.ui.cb_starting_node.currentText() end = self.ui.cb_ending_node.currentText() weight = self.ui.sb_weight_edge.value() if start and end: self.add_cb_item(start) self.add_cb_item(end) self.graph.add_edge(start, end, label=weight) self.redraw() @pyqtSlot() def on_bt_del_edge_clicked(self): """ Slot when click on Delete branch button """ start = self.ui.cb_starting_node.currentText() end = self.ui.cb_ending_node.currentText() weight = self.ui.sb_weight_edge.value() if start and end and self.graph.has_edge(start, end): self.graph.remove_edge(start, end) self.redraw() @pyqtSlot(int) @pyqtSlot(bool, name='on_bt_add_node_clicked') @pyqtSlot(bool, name='on_bt_del_node_clicked') @pyqtSlot(bool, name='on_bt_add_edge_clicked') @pyqtSlot(bool, name='on_bt_del_edge_clicked') def on_toolbox_view_currentChanged(self, index): index = self.ui.toolbox_view.currentIndex() if index == 0: self.update_adj_matrix() elif index == 1: self.update_matrix_incidence() elif index == 2: self.update_list_edges() elif index == 3: self.update_adj_list()