def create_widget(self): self.scene = QGraphicsScene(self.parent_widget()) self.widget = ZoomingGraphicsView(self.parent_widget()) self.widget.setScene(self.scene) self.widget.setDragMode(QGraphicsView.ScrollHandDrag) self.widget.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing)
class QtGraph(QtFrame, ProxyGraph): widget = Typed(QGraphicsView) scene = Typed(QGraphicsScene) _proxies = {} _edge_paths = List() LEFT_PADDING = 1200 TOP_PADDING = 1200 def create_widget(self): self.scene = QGraphicsScene(self.parent_widget()) self.widget = ZoomingGraphicsView(self.parent_widget()) self.widget.setScene(self.scene) self.widget.setDragMode(QGraphicsView.ScrollHandDrag) self.widget.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing) def child_added(self, child): super(QtGraph, self).child_added(child) self._proxy(child) def child_removed(self, child): super(QtGraph, self).child_removed(child) if child in self._proxies: self.scene.removeItem(self._proxies[child]) def init_layout(self): super(QtGraph, self).init_layout() self.request_relayout() def _proxy(self, child): if child not in self._proxies: cw = child.widget if cw is not None: cw.setParent(None) self._proxies[child] = self.scene.addWidget(cw) return self._proxies[child] def request_relayout(self): # y = 0.0 # for child in self.children(): # if not isinstance(child, QtContainer): # continue # scene_proxy = self._proxies[child] # width, height = child._layout_manager.best_size() # scene_proxy.setPos(0.0, y) # y += height + 25.0 for p in self._edge_paths: self.scene.removeItem(p) self._edge_paths = [] g = pygraphviz.AGraph(directed=True) g.graph_attr['nodesep'] = 100 g.graph_attr['ranksep'] = 50 g.node_attr['shape'] = 'rect' children_names = {child.declaration.name for child in self.children() if isinstance(child, QtContainer)} if any(from_ not in children_names or to not in children_names for (from_, to) in self.declaration.edges): # hasn't finished being set up yet return for child in self.children(): if not isinstance(child, QtContainer): continue scene_proxy = self._proxy(child) width, height = child._layout_manager.best_size() scene_proxy.setGeometry(QRectF(0.0, 0.0, width, height)) g.add_node(child.declaration.name, width=width, height=height) for from_, to in self.declaration.edges: g.add_edge(from_, to) g.layout(prog='dot') for child in self.children(): if not isinstance(child, QtContainer): continue scene_proxy = self._proxies[child] node = g.get_node(child.declaration.name) center_x, center_y = (-float(v)/72.0 for v in node.attr['pos'].split(',')) width, height = child._layout_manager.best_size() x = center_x - (width / 2.0) y = center_y - (height / 2.0) scene_proxy.setPos(x, y) for from_, to in self.declaration.edges: if from_ not in children_names or to not in children_names: continue edge = g.get_edge(from_, to) # TODO: look at below code all_points = [tuple(-float(v)/72.0 for v in t.strip('e,').split(',')) for t in edge.attr['pos'].split(' ')] arrow = all_points[0] start_point = all_points[1] painter = QPainterPath(QPointF(*start_point)) for c1, c2, end in grouper(all_points[2:], 3): painter.cubicTo(QPointF(*c1), QPointF(*c2), QPointF(*end)) self._edge_paths.append(self.scene.addPath(painter)) rect = self.scene.itemsBoundingRect() # Enlarge the rect so there is enough room at right and bottom rect.setX(rect.x() - self.LEFT_PADDING) rect.setY(rect.y() - self.TOP_PADDING) rect.setWidth(rect.width() + 2 * self.LEFT_PADDING) rect.setHeight(rect.height() + 2 * self.TOP_PADDING) self.scene.setSceneRect(rect) self.widget.viewport().update() self.show_selected() def minimumSizeHint(self): return QSize(0, 0) def show_selected(self): # TODO: make more efficient? for child, proxy in self._proxies.items(): if isinstance(child, QtContainer) and child.declaration is not None and child.declaration.name == self.declaration.selected: self.widget.ensureVisible(proxy) break
class QtGraph(QtFrame, ProxyGraph): widget = Typed(QGraphicsView) scene = Typed(QGraphicsScene) _proxies = Dict() _edge_paths = List() def create_widget(self): self.scene = QGraphicsScene(self.parent_widget()) self.widget = ZoomingGraphicsView(self.parent_widget()) self.widget.setScene(self.scene) self.widget.setDragMode(QGraphicsView.ScrollHandDrag) self.widget.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing) def child_added(self, child): super(QtGraph, self).child_added(child) self._proxy(child) def child_removed(self, child): super(QtGraph, self).child_removed(child) if child in self._proxies: self.scene.removeItem(self._proxies[child]) def init_layout(self): super(QtGraph, self).init_layout() self.request_relayout() def _proxy(self, child): if child not in self._proxies: cw = child.widget if cw is not None: cw.setParent(None) self._proxies[child] = self.scene.addWidget(cw) return self._proxies[child] def request_relayout(self): # y = 0.0 # for child in self.children(): # if not isinstance(child, QtContainer): # continue # scene_proxy = self._proxies[child] # width, height = child._layout_manager.best_size() # scene_proxy.setPos(0.0, y) # y += height + 25.0 for p in self._edge_paths: self.scene.removeItem(p) self._edge_paths = [] g = pygraphviz.AGraph(directed=True) g.graph_attr['nodesep'] = 100 g.graph_attr['ranksep'] = 50 g.node_attr['shape'] = 'rect' children_names = {child.declaration.name for child in self.children() if isinstance(child, QtContainer)} if any(from_ not in children_names or to not in children_names for (from_, to) in self.declaration.edges): # hasn't finished being set up yet return for child in self.children(): if not isinstance(child, QtContainer): continue scene_proxy = self._proxy(child) width, height = child._layout_manager.best_size() scene_proxy.setGeometry(QRectF(0.0, 0.0, width, height)) g.add_node(child.declaration.name, width=width, height=height) for from_, to in self.declaration.edges: g.add_edge(from_, to) before = time.time() g.layout(prog='dot') after = time.time() for child in self.children(): if not isinstance(child, QtContainer): continue scene_proxy = self._proxies[child] node = g.get_node(child.declaration.name) center_x, center_y = (-float(v)/72.0 for v in node.attr['pos'].split(',')) width, height = child._layout_manager.best_size() x = center_x - (width / 2.0) y = center_y - (height / 2.0) scene_proxy.setPos(x, y) for from_, to in self.declaration.edges: if from_ not in children_names or to not in children_names: continue edge = g.get_edge(from_, to) # TODO: look at below code all_points = [tuple(-float(v)/72.0 for v in t.strip('e,').split(',')) for t in edge.attr['pos'].split(' ')] arrow = all_points[0] start_point = all_points[1] painter = QPainterPath(QPointF(*start_point)) for c1, c2, end in grouper(all_points[2:], 3): painter.cubicTo(QPointF(*c1), QPointF(*c2), QPointF(*end)) self._edge_paths.append(self.scene.addPath(painter)) self.show_selected() def minimumSizeHint(self): return QSize(0, 0) def show_selected(self): # TODO: make more efficient? for child, proxy in self._proxies.items(): if isinstance(child, QtContainer) and child.declaration is not None and child.declaration.name == self.declaration.selected: self.widget.ensureVisible(proxy) break