def getNodeItemForNode(self, node, highlight_level): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ["attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) node.attr = attr if "style" in node.attr: if node.attr["style"] == "invis": return None color = QColor(node.attr["color"]) if "color" in node.attr else None name = None if "label" in node.attr: name = node.attr["label"] elif "name" in node.attr: name = node.attr["name"] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print("Error, label is None for node %s, pygraphviz version may be too old." % node) else: name = name.decode("string_escape") # decrease rect by one so that edges do not reach inside bb_width = len(name) / 5 if "width" in node.attr: bb_width = node.attr["width"] bb_height = 1.0 if "width" in node.attr: bb_height = node.attr["height"] bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) pos = (0, 0) if "pos" in node.attr: pos = node.attr["pos"].split(",") bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) node_item = NodeItem( highlight_level=highlight_level, bounding_box=bounding_box, label=name, shape=node.attr.get("shape", "ellipse"), color=color, tooltip=node.attr.get("tooltip", None) # parent=None, # label_pos=None ) # node_item.setToolTip(self._generate_tool_tip(node.attr.get('URL', None))) return node_item
def getNodeItemForNode(self, node, highlight_level): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api # attr = {} # for name in node.get_attributes().iterkeys(): # value = get_unquoted(node, name) # attr[name] = value # obj_dic = node.__getattribute__("obj_dict") # for name in obj_dic: # if name not in ['attributes', 'parent_graph'] and obj_dic[name] is not None: # attr[name] = get_unquoted(obj_dic, name) # node.attr = attr if 'style' in node.attr: if node.attr['style'] == 'invis': return None color = QColor(node.attr['color']) if 'color' in node.attr else None name = None if 'label' in node.attr: name = node.attr['label'] elif 'name' in node.attr: name = node.attr['name'] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print("Error, label is None for node %s, pygraphviz version may be too old." % node) else: name = name.decode('string_escape') # decrease rect by one so that edges do not reach inside bb_width = len(name) / 5 if 'width' in node.attr: bb_width = node.attr['width'] bb_height = 1.0 if 'width' in node.attr: bb_height = node.attr['height'] bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) pos = (0, 0) if 'pos' in node.attr: pos = node.attr['pos'].split(',') bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) node_item = NodeItem(highlight_level=highlight_level, bounding_box=bounding_box, label=name, shape=node.attr.get('shape', 'ellipse'), color=color, tooltip=node.attr.get('tooltip', None) # parent=None, # label_pos=None ) # node_item.setToolTip(self._generate_tool_tip(node.attr.get('URL', None))) return node_item
def create_node(self, bounding_box, shape, label, label_pos=None, url=None, parent=None, cluster=False, **kwargs): self._check_constraints(kwargs) node_item = HoveredNodeItem(bounding_box, shape, label, label_pos, url, parent, **kwargs) if cluster: bounding_box = QRectF(bounding_box) bounding_box.setHeight(30) node_item.set_hover_shape(bounding_box) return node_item
def paint(self, painter, option, widget): # Main rectangle rectangle = QRectF(self._bounding_box.topLeft().x(), self._bounding_box.topLeft().y() + self._bounding_box.height() * 0.1, self._bounding_box.width() - self._bounding_box.height() * 0.1, self._bounding_box.height() - self._bounding_box.height() * 0.1) painter.drawRect(rectangle) # Top line painter.drawLine(rectangle.topLeft().x() + self._bounding_box.height() * 0.1, self._bounding_box.topLeft().y(), self._bounding_box.topRight().x(), self._bounding_box.topRight().y()) # Top left corner painter.drawLine(rectangle.topLeft().x() + self._bounding_box.height() * 0.1, self._bounding_box.topLeft().y(), self._bounding_box.topLeft().x() + 1, rectangle.topLeft().y()) # Top right corner painter.drawLine(self._bounding_box.topRight().x(), self._bounding_box.topRight().y(), rectangle.topRight().x(), rectangle.topRight().y()) # Bottom right corner painter.drawLine(rectangle.bottomRight().x() + 1, rectangle.bottomRight().y() - 1, self._bounding_box.bottomRight().x(), rectangle.bottomRight().y() - self._bounding_box.height() * 0.1) # Right line painter.drawLine(self._bounding_box.topRight().x(), self._bounding_box.topRight().y(), self._bounding_box.topRight().x(), self._bounding_box.bottomRight().y() - self._bounding_box.height() * 0.1)
def getNodeItemForSubgraph(self, subgraph, highlight_level, scene=None): # let pydot imitate pygraphviz api attr = {} for name in subgraph.get_attributes().keys(): value = get_unquoted(subgraph, name) attr[name] = value obj_dic = subgraph.__getattribute__('obj_dict') for name in obj_dic: if name not in ['nodes', 'attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == 'nodes': for key in obj_dic['nodes']['graph'][0]['attributes']: attr[key] = get_unquoted( obj_dic['nodes']['graph'][0]['attributes'], key) subgraph.attr = attr bb = subgraph.attr.get('bb', None) if bb is None: # no bounding box return None bb = bb.strip('"').split(',') if len(bb) < 4: # bounding box is empty return None bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1])) if 'lp' in subgraph.attr: label_pos = subgraph.attr['lp'].strip('"').split(',') else: label_pos = (float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2) bounding_box.moveCenter( QPointF( float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2)) name = subgraph.attr.get('label', '') color = QColor( subgraph.attr['color']) if 'color' in subgraph.attr else None subgraph_nodeitem = NodeItem( highlight_level, bounding_box, label=name, shape='box', color=color, parent=scene.activePanel() if scene is not None else None, label_pos=QPointF(float(label_pos[0]), -float(label_pos[1]))) bounding_box = QRectF(bounding_box) # With clusters we have the problem that mouse hovers cannot # decide whether to be over the cluster or a subnode. Using # just the "title area" solves this. TODO: Maybe using a # border region would be even better (multiple RectF) bounding_box.setHeight(LABEL_HEIGHT) subgraph_nodeitem.set_hovershape(bounding_box) if scene is not None: scene.addItem(subgraph_nodeitem) return subgraph_nodeitem
def create_node(self, bounding_box, shape, label, label_pos=None, url=None, parent=None, cluster=False, **kwargs): self._check_constraints(kwargs) if label.startswith('<') and label.endswith('>'): node_item = DmgHtmlNodeItem(bounding_box, shape, label[1:-1], label_pos, url, parent, **kwargs) else: node_item = DmgNodeItem(bounding_box, shape, label, label_pos, url, parent, **kwargs) if cluster: bounding_box = QRectF(bounding_box) bounding_box.setHeight(30) node_item.set_hover_shape(bounding_box) return node_item
def get_cluster_node(self, node): # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ["nodes", "attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == "nodes": for key in obj_dic["nodes"]["graph"][0]["attributes"]: attr[key] = get_unquoted(obj_dic["nodes"]["graph"][0]["attributes"], key) node.attr = attr name = None if "label" in node.attr: name = node.attr["label"] elif "name" in node.attr: name = node.attr["name"] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print("Error, label is None for node %s, pygraphviz version may be too old." % node) bb_width = node.attr["width"] bb_height = node.attr["height"] bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) # print bounding_box pos = (0, 0) if "pos" in node.attr: pos = node.attr["pos"].split(",") bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) label_pos = QPointF(bounding_box.center().x(), bounding_box.top() + LABEL_HEIGHT / 2) color = QColor(node.attr["color"]) if "color" in node.attr else None url = node.attr["URL"] if "URL" in node.attr else "N/A" label = node.attr["label"] if "label" in node.attr else name graph_node_item = self._factory.create_node( bounding_box=bounding_box, shape="box", label=label, label_pos=label_pos, url=url, cluster=True ) return graph_node_item
def getNodeItemForNode(self, node, highlight_level, scene=None): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ['attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) node.attr = attr if node.attr.get('style') == 'invis': return None color = QColor(node.attr['color']) if 'color' in node.attr else None name = node.attr.get('label', node.attr.get('name')) if name is None: print("Error, no label defined for node with attr: %s" % node.attr) return None name = name.decode('string_escape') # decrease rect by one so that edges do not reach inside bb_width = node.attr.get('width', len(name) / 5) bb_height = node.attr.get('height', 1.0) bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) pos = node.attr.get('pos', '0,0').split(',') bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) node_item = NodeItem( highlight_level=highlight_level, bounding_box=bounding_box, label=name, shape=node.attr.get('shape', 'ellipse'), color=color, tooltip=node.attr.get('tooltip'), parent=scene.activePanel() if scene is not None else None #label_pos=None ) if scene is not None: scene.addItem(node_item) return node_item
def drawField(self, painter): # draw green surface rectangle painter.setPen(Qt.black) painter.setBrush(Qt.green) rx = -self.world_width * 0.5 ry = -self.world_height * 0.5 rect = QRectF(rx, ry, self.world_width, self.world_height) painter.drawRect(rect) # draw white lines painter.setPen(QPen(Qt.white,2)) for line in self.field_geometry.field_lines: p1 = self.convertToDrawWorld(line.p1_x, line.p1_y) p2 = self.convertToDrawWorld(line.p2_x, line.p2_y) painter.drawLine(p1, p2) for arc in self.field_geometry.field_arcs: top_left = self.convertToDrawWorld( arc.center_x - arc.radius, arc.center_y + arc.radius) size = arc.radius * 2.0 * self.scaleOnField start_angle = math.degrees(arc.a1) end_angle = math.degrees(arc.a2) span_angle = end_angle - start_angle # angle must be 1/16 degrees order start_angle *= 16 span_angle *= 16 painter.drawArc(top_left.x(), top_left.y(), size, size, start_angle, span_angle)
def _draw_field(self, painter): # フィールドの緑と白線を描画する # グリーンカーペットを描画 painter.setPen(Qt.black) painter.setBrush(Qt.green) rect = QRectF(-self._view_width * 0.5, -self._view_height * 0.5, self._view_width, self._view_height) painter.drawRect(rect) # 白線を描画 painter.setPen(QPen(Qt.white, self._WHITE_LINE_THICKNESS)) for line in self._field_lines: p1 = self._convert_to_view(line["p1_x"], line["p1_y"]) p2 = self._convert_to_view(line["p2_x"], line["p2_y"]) painter.drawLine(p1, p2) for arc in self._field_arcs: top_left = self._convert_to_view(arc["center_x"] - arc["radius"], arc["center_y"] + arc["radius"]) size = arc["radius"] * 2.0 * self._scale_field_to_view # angle must be 1/16 degrees order start_angle = math.degrees(arc["a1"]) * 16 end_angle = math.degrees(arc["a2"]) * 16 span_angle = end_angle - start_angle painter.drawArc(top_left.x(), top_left.y(), size, size, start_angle, span_angle)
def add_ROI(self, pixel_coords): self.regionCounter += 1 markerSize = 25 ellipse_item = QGraphicsEllipseItem( QRectF( QPointF(pixel_coords.x() - markerSize / 2, pixel_coords.y() - markerSize / 2), QSizeF(markerSize, markerSize))) ellipse_item.setBrush(QBrush(QColor('red'))) self.addItem(ellipse_item) label_font = QFont() label_font.setPointSize(15) region_string = 'r' + str(self.regionCounter).zfill(2) ellipse_item_label = QGraphicsTextItem(region_string) ellipse_item_label.setPos(pixel_coords) ellipse_item_label.setFont(label_font) self.addItem(ellipse_item_label) self.items_dict.update({ region_string: { 'ellipse_item': ellipse_item, 'ellipse_item_label': ellipse_item_label, 'pixel_coords': pixel_coords, 'ap_item_label': {} } })
def paintEvent(self, event): # super(QLabel, self).repaint(rect) painter = QPainter(self) # print "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2", event.rect() # painter.fillRect(event.rect(), Qt.darkGray) doc = QTextDocument() highlight = syntax.PythonHighlighter(doc, is_dark = True, default = ['white']) font = self.font() # font.setFamily("Courier"); font.setStyleHint(QFont.Monospace); font.setFixedPitch(True); # font.setPointSize(self.font().pointSize()); doc.setDefaultFont(font) self.width = event.rect().width() # doc.setTextWidth(self.width()) text = self.text() doc.setPlainText(text) painter.translate(0., event.rect().center().y() - doc.size().height()/2.) doc.drawContents(painter, QRectF(event.rect())) painter.resetTransform() self.size = doc.size() # print "repainting" pass
def _load_default_image(self): joystick_icon = os.path.join( rospkg.RosPack().get_path('rocon_bubble_icons'), 'icons', 'joystick.png') pixmap = QPixmap(joystick_icon, format="png") self.scene.addPixmap(pixmap) self.scene.update() self.fitInView(QRectF(0, 0, self.scene.width(), self.scene.height()), Qt.KeepAspectRatio)
def get_cluster_node(self, node): # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ['nodes', 'attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == 'nodes': for key in obj_dic['nodes']['graph'][0]['attributes']: attr[key] = get_unquoted( obj_dic['nodes']['graph'][0]['attributes'], key) node.attr = attr name = None if 'label' in node.attr: name = node.attr['label'] elif 'name' in node.attr: name = node.attr['name'] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print( "Error, label is None for node %s, pygraphviz version may be too old." % node) bb_width = node.attr['width'] bb_height = node.attr['height'] bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) # print bounding_box pos = (0, 0) if 'pos' in node.attr: pos = node.attr['pos'].split(',') bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) label_pos = QPointF(bounding_box.center().x(), bounding_box.top() + LABEL_HEIGHT / 2) color = QColor(node.attr['color']) if 'color' in node.attr else None url = node.attr['URL'] if 'URL' in node.attr else 'N/A' label = node.attr['label'] if 'label' in node.attr else name graph_node_item = self._factory.create_node(bounding_box=bounding_box, shape='box', label=label, label_pos=label_pos, url=url, cluster=True) return graph_node_item
def mousePressEvent(self, mouse_event): self._last_pan_point = mouse_event.pos() self._last_scene_center = self._map_to_scene_f( QRectF(self.frameRect()).center()) self.setCursor(Qt.ClosedHandCursor) item = self.itemAt(self._last_pan_point) if item: #If clicked text or bounding box then give correspondent parent NodeItem if isinstance(item.parentItem(), NodeItem): nodename = str(item.parentItem()._label.text()) #Edit node event self.cb_clicknode(nodename)
def on_compressed_image_received(self, image): ''' :param sensor_msgs.CompressedImage image: convert and display this in the QGraphicsView. ''' if len(self.scene.items()) > 1: self.scene.removeItem(self.scene.items()[0]) pixmap = QPixmap() pixmap.loadFromData(image.data, format=image.format) self.scene.addPixmap(pixmap) self.scene.update() # setting fitInvView seems sensitive to here or prior to scene update self.fitInView(QRectF(0, 0, self.scene.width(), self.scene.height()), Qt.KeepAspectRatio)
def _handle_add_clicked(self): name = self.name_edit.text() if len(name) != 0: # remove and re-draw it if name in self.places_dict.keys(): self.places_dict.pop(name) for item in self._sceneItems[name].keys(): self._scene.removeItem(self._sceneItems[name][item]) try: # storing the values in the dict x = self.x_spin.value() y = self.y_spin.value() theta = self.theta_spin.value() q = quaternion_from_euler(0.0, 0.0, theta) self.places_dict[str(name)] = [ x, y, 0.0, float(q[0]), float(q[1]), float(q[2]), float(q[3]) ] # drawing the items self._sceneItems[name] = {"text": QGraphicsTextItem()} self._sceneItems[name]["text"].setDefaultTextColor( QColor(0, 0, 255)) self._sceneItems[name]["text"].setFont(QFont("Times", 10)) self._sceneItems[name]["text"].setPlainText(name) scene_pos = self._gridToScene(x, y, q) x_c = scene_pos[0] - self._sceneItems[name][ "text"].boundingRect().width() / 2.0 self._sceneItems[name]["text"].setPos(x_c, scene_pos[1]) self._scene.addItem(self._sceneItems[name]["text"]) self._sceneItems[name]["rec"] = self._scene.addRect( QRectF((scene_pos[0] - 2), (scene_pos[1] - 2), 4, 4)) line = QLineF( scene_pos[0], scene_pos[1], (scene_pos[0] - self._mag * cos(radians(scene_pos[3]))), (scene_pos[1] + self._mag * sin(radians(scene_pos[3])))) self._sceneItems[name]["line"] = self._scene.addLine( line, pen=QPen(Qt.red, 2)) except ValueError: QMessageBox.critical(self, "Error!", "You must insert a valid value.") else: QMessageBox.critical( self, "Error!", "You have to insert a name and a valid position.")
def getNodeItemForSubgraph(self, subgraph, highlight_level): # let pydot imitate pygraphviz api attr = {} for name in subgraph.get_attributes().iterkeys(): value = get_unquoted(subgraph, name) attr[name] = value obj_dic = subgraph.__getattribute__("obj_dict") for name in obj_dic: if name not in ["nodes", "attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == "nodes": for key in obj_dic["nodes"]["graph"][0]["attributes"]: attr[key] = get_unquoted(obj_dic["nodes"]["graph"][0]["attributes"], key) subgraph.attr = attr bb = subgraph.attr.get("bb", None) if bb is None: # no bounding box return None bb = bb.strip('"').split(",") if len(bb) < 4: # bounding box is empty return None bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1])) if "lp" in subgraph.attr: label_pos = subgraph.attr["lp"].strip('"').split(",") else: label_pos = ( float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2, ) bounding_box.moveCenter( QPointF(float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2) ) name = subgraph.attr.get("label", "") color = QColor(subgraph.attr["color"]) if "color" in subgraph.attr else None subgraph_nodeitem = NodeItem( highlight_level, bounding_box, label=name, shape="box", color=color, label_pos=QPointF(float(label_pos[0]), -float(label_pos[1])), ) bounding_box = QRectF(bounding_box) # With clusters we have the problem that mouse hovers cannot # decide whether to be over the cluster or a subnode. Using # just the "title area" solves this. TODO: Maybe using a # border region would be even better (multiple RectF) bounding_box.setHeight(LABEL_HEIGHT) subgraph_nodeitem.set_hovershape(bounding_box) return subgraph_nodeitem
def _display_image(self): image = self.teleop_app_info.image_data if image: if len(self.scene.items()) > 1: self.scene.removeItem(self.scene.items()[0]) image_data = self.teleop_app_info.image_data.data pixmap = QPixmap() pixmap.loadFromData( image_data, format="PNG", ) self._widget.camera_view.fitInView( QRectF(0, 0, pixmap.width(), pixmap.height()), Qt.KeepAspectRatio) self.scene.addPixmap(pixmap) self.scene.update() else: self.scene.clear()
def _handle_load_clicked(self): filename = QFileDialog.getOpenFileName( self, self.tr('Load from File'), '.', self.tr('YAML files {.yaml} (*.yaml)')) if filename[0] != '': with open(filename[0], 'r') as infile: try: self.places_dict = yaml.load(infile) for k in self._sceneItems.keys(): for item in self._sceneItems[k].keys(): self._scene.removeItem(self._sceneItems[k][item]) for name in self.places_dict.keys(): # q = numpy.asarray(self.places_dict[name][3:7]) scene_pos = self._gridToScene( self.places_dict[name][0], self.places_dict[name][1], q) # drawing the items self._sceneItems[name] = {"text": QGraphicsTextItem()} self._sceneItems[name]["text"].setDefaultTextColor( QColor(0, 0, 255)) self._sceneItems[name]["text"].setFont( QFont("Times", 10)) self._sceneItems[name]["text"].setPlainText(name) x_c = scene_pos[0] - self._sceneItems[name][ "text"].boundingRect().width() / 2.0 self._sceneItems[name]["text"].setPos( x_c, scene_pos[1]) self._scene.addItem(self._sceneItems[name]["text"]) self._sceneItems[name]["rec"] = self._scene.addRect( QRectF((scene_pos[0] - 2), (scene_pos[1] - 2), 4, 4)) line = QLineF(scene_pos[0], scene_pos[1], (scene_pos[0] - self._mag * cos(radians(scene_pos[3]))), (scene_pos[1] + self._mag * sin(radians(scene_pos[3])))) self._sceneItems[name]["line"] = self._scene.addLine( line, pen=QPen(Qt.red, 2)) except yaml.scanner.ScannerError: QMessageBox.critical(self, "Error!", "Invalid YAML file.")
def paintEvent(self, event): painter = QPainter(self) doc = QTextDocument() highlight = syntax.PythonHighlighter(doc, is_dark = True, default = ['white']) font = self.font() font.setStyleHint(QFont.Monospace); font.setFixedPitch(True); doc.setDefaultFont(font) self.width = event.rect().width() text = self.text() doc.setPlainText(text) painter.translate(0., event.rect().center().y() - doc.size().height()/2.) doc.drawContents(painter, QRectF(event.rect())) painter.resetTransform() self.size = doc.size()
def _y_changed(self, value): name = self.name_edit.text() if (len(name) != 0) and (name in self.places_dict.keys()): self._scene.removeItem(self._sceneItems[name]["line"]) self._scene.removeItem(self._sceneItems[name]["rec"]) grid_pos = self.places_dict[name] scene_pos = self._gridToScene(grid_pos[0], value, numpy.asarray(grid_pos[3:7])) x_c = scene_pos[0] - self._sceneItems[name]["text"].boundingRect( ).width() / 2.0 self._sceneItems[name]["text"].setPos(x_c, scene_pos[1]) self._sceneItems[name]["rec"] = self._scene.addRect( QRectF((scene_pos[0] - 2), (scene_pos[1] - 2), 4, 4)) line = QLineF( scene_pos[0], scene_pos[1], (scene_pos[0] - self._mag * cos(radians(scene_pos[3]))), (scene_pos[1] + self._mag * sin(radians(scene_pos[3])))) self._sceneItems[name]["line"] = self._scene.addLine(line, pen=QPen( Qt.red, 2)) self.places_dict[name][1] = value
def mousePressEvent(self, mouse_event): self._last_pan_point = mouse_event.pos() self._last_scene_center = self._map_to_scene_f(QRectF(self.frameRect()).center()) self.setCursor(Qt.ClosedHandCursor) QGraphicsView.mousePressEvent(self, mouse_event)
def get_subgraph_nodes(self, graph, nodes): # let pydot imitate pygraphviz api attr = {} for name in graph.get_attributes().iterkeys(): value = get_unquoted(graph, name) attr[name] = value obj_dic = graph.__getattribute__("obj_dict") for name in obj_dic: if name not in ["nodes", "attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == "nodes": for key in obj_dic["nodes"]["graph"][0]["attributes"]: attr[key] = get_unquoted(obj_dic["nodes"]["graph"][0]["attributes"], key) graph.attr = attr bb = graph.attr["bb"].strip('"').split(",") if len(bb) < 4: # bounding box is empty return None bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1])) if "lp" in graph.attr: label_pos = graph.attr["lp"].strip('"').split(",") else: label_pos = ( float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2, ) bounding_box.moveCenter( QPointF(float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2) ) name = graph.attr.get("label", "") color = QColor(graph.attr["color"]) if "color" in graph.attr else None url = graph.attr["URL"] if "URL" in graph.attr else "N/A" graph_node_item = self._factory.create_node( bounding_box=bounding_box, shape="box", label=name, label_pos=QPointF(float(label_pos[0]), -float(label_pos[1])), url=url, cluster=True, ) for subgraph in graph.get_subgraph_list(): subgraph_node_item = self.get_subgraph_nodes(subgraph, nodes) # skip subgraphs with empty bounding boxes if subgraph_node_item is None: continue nodes[subgraph.get_name()] = subgraph_node_item for node in subgraph.get_node_list(): # hack required by pydot if node.get_name() in ("graph", "node", "empty"): continue nodes[node.get_name()] = self.get_node_item_for_node(node) for node in graph.get_node_list(): # hack required by pydot if node.get_name() in ("graph", "node", "empty"): continue nodes[node.get_name()] = self.get_node_item_for_node(node) return graph_node_item
def get_node_item_for_node(self, node): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ["attributes", "parent_graph"] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) node.attr = attr if "style" in node.attr: if node.attr["style"] == "invis": return None color = QColor(node.attr["color"]) if "color" in node.attr else None name = None if "label" in node.attr: name = node.attr["label"] elif "name" in node.attr: name = node.attr["name"] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print("Error, label is None for node %s, pygraphviz version may be too old." % node) else: name = name.decode("string_escape") # decrease rect by one so that edges do not reach inside bb_width = len(name) / 5 if "width" in node.attr: bb_width = node.attr["width"] bb_height = 1.0 if "width" in node.attr: bb_height = node.attr["height"] pos = (0, 0) if "pos" in node.attr: pos = node.attr["pos"].split(",") bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) pen_width = self._factory.pen_width() if "penwidth" in node.attr: pen_width = float(node.attr["penwidth"]) url = node.attr["URL"] if "URL" in node.attr else "N/A" node_item = self._factory.create_node( bounding_box=bounding_box, shape=node.attr.get("shape", "box"), label=name, url=url, penwidth=pen_width ) return node_item
def get_node_item_for_node(self, node): """ returns a pyqt NodeItem object, or None in case of error or invisible style """ # let pydot imitate pygraphviz api attr = {} for name in node.get_attributes().iterkeys(): value = get_unquoted(node, name) attr[name] = value obj_dic = node.__getattribute__("obj_dict") for name in obj_dic: if name not in ['attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) node.attr = attr if 'style' in node.attr: if node.attr['style'] == 'invis': return None color = QColor(node.attr['color']) if 'color' in node.attr else None name = None if 'label' in node.attr: name = node.attr['label'] elif 'name' in node.attr: name = node.attr['name'] else: print("Error, no label defined for node with attr: %s" % node.attr) return None if name is None: # happens on Lucid pygraphviz version print( "Error, label is None for node %s, pygraphviz version may be too old." % node) else: name = name.decode('string_escape') # decrease rect by one so that edges do not reach inside bb_width = len(name) / 5 if 'width' in node.attr: bb_width = node.attr['width'] bb_height = 1.0 if 'width' in node.attr: bb_height = node.attr['height'] pos = (0, 0) if 'pos' in node.attr: pos = node.attr['pos'].split(',') bounding_box = QRectF(0, 0, POINTS_PER_INCH * float(bb_width) - 1.0, POINTS_PER_INCH * float(bb_height) - 1.0) bounding_box.moveCenter(QPointF(float(pos[0]), -float(pos[1]))) pen_width = self._factory.pen_width() if 'penwidth' in node.attr: pen_width = float(node.attr['penwidth']) url = node.attr['URL'] if 'URL' in node.attr else 'N/A' node_item = self._factory.create_node(bounding_box=bounding_box, shape=node.attr.get( 'shape', 'box'), label=name, url=url, penwidth=pen_width) return node_item
def get_subgraph_nodes(self, graph, nodes): # let pydot imitate pygraphviz api attr = {} for name in graph.get_attributes().iterkeys(): value = get_unquoted(graph, name) attr[name] = value obj_dic = graph.__getattribute__("obj_dict") for name in obj_dic: if name not in ['nodes', 'attributes', 'parent_graph' ] and obj_dic[name] is not None: attr[name] = get_unquoted(obj_dic, name) elif name == 'nodes': for key in obj_dic['nodes']['graph'][0]['attributes']: attr[key] = get_unquoted( obj_dic['nodes']['graph'][0]['attributes'], key) graph.attr = attr bb = graph.attr['bb'].strip('"').split(',') if len(bb) < 4: # bounding box is empty return None bounding_box = QRectF(0, 0, float(bb[2]) - float(bb[0]), float(bb[3]) - float(bb[1])) if 'lp' in graph.attr: label_pos = graph.attr['lp'].strip('"').split(',') else: label_pos = (float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, float(bb[1]) + (float(bb[3]) - float(bb[1])) - LABEL_HEIGHT / 2) bounding_box.moveCenter( QPointF( float(bb[0]) + (float(bb[2]) - float(bb[0])) / 2, -float(bb[1]) - (float(bb[3]) - float(bb[1])) / 2)) name = graph.attr.get('label', '') color = QColor(graph.attr['color']) if 'color' in graph.attr else None url = graph.attr['URL'] if 'URL' in graph.attr else 'N/A' graph_node_item = self._factory.create_node(bounding_box=bounding_box, shape='box', label=name, label_pos=QPointF( float(label_pos[0]), -float(label_pos[1])), url=url, cluster=True) for subgraph in graph.get_subgraph_list(): subgraph_node_item = self.get_subgraph_nodes(subgraph, nodes) # skip subgraphs with empty bounding boxes if subgraph_node_item is None: continue nodes[subgraph.get_name()] = subgraph_node_item for node in subgraph.get_node_list(): # hack required by pydot if node.get_name() in ('graph', 'node', 'empty'): continue nodes[node.get_name()] = self.get_node_item_for_node(node) for node in graph.get_node_list(): # hack required by pydot if node.get_name() in ('graph', 'node', 'empty'): continue nodes[node.get_name()] = self.get_node_item_for_node(node) return graph_node_item
def boundingRect(self): return QRectF(0, 0, 100, 100)
def resizeEvent(self, evt=None): self.fitInView(QRectF(0, 0, self.scene.width(), self.scene.height()), Qt.KeepAspectRatio)
def boundingRect(self): return QRectF(0, 0, SandtrayItem.length * SandtrayItem.scale, SandtrayItem.width * SandtrayItem.scale)
def drawField(self, painter): # draw green surface rectangle painter.setPen(Qt.black) painter.setBrush(Qt.green) rx = -self.fieldWidth * 0.5 ry = -self.fieldHeight * 0.5 rect = QRectF(rx, ry, self.fieldWidth, self.fieldHeight) painter.drawRect(rect) # draw wall rectangle painter.setPen(QPen(Qt.black, 3)) painter.setBrush(Qt.NoBrush) sizeX = self.CW.WALL_WIDTH * self.scaleOnField sizeY = self.CW.WALL_HEIGHT * self.scaleOnField rx = -sizeX * 0.5 ry = -sizeY * 0.5 rect = QRectF(rx, ry, sizeX, sizeY) painter.drawRect(rect) # draw center circle painter.setPen(QPen(Qt.white, 2)) point = self.convertToDrawWorld(0.0, 0.0) size = self.CW.FIELD_CENTER_RADIUS * self.scaleOnField painter.drawEllipse(point, size, size) # draw play field rectangle sizeX = self.CW.PLAY_FIELD_WIDTH * self.scaleOnField sizeY = self.CW.PLAY_FIELD_HEIGHT * self.scaleOnField rx = -sizeX * 0.5 ry = -sizeY * 0.5 rect = QRectF(rx, ry, sizeX, sizeY) painter.drawRect(rect) # draw mid-line point1 = self.convertToDrawWorld(-self.CW.PLAY_FIELD_WIDTH * 0.5, 0) point2 = self.convertToDrawWorld(self.CW.PLAY_FIELD_WIDTH * 0.5, 0) painter.drawLine(point1, point2) # draw center line point1 = self.convertToDrawWorld(0, self.CW.PLAY_FIELD_HEIGHT * 0.5) point2 = self.convertToDrawWorld(0, -self.CW.PLAY_FIELD_HEIGHT * 0.5) painter.drawLine(point1, point2) # draw streach line x = self.CW.PLAY_FIELD_WIDTH * 0.5 - self.CW.FIELD_DEFENCE_RADIUS point1 = self.convertToDrawWorld(x, self.CW.FIELD_STREACH * 0.5) point2 = self.convertToDrawWorld(x, -self.CW.FIELD_STREACH * 0.5) painter.drawLine(point1, point2) x *= -1.0 point1 = self.convertToDrawWorld(x, self.CW.FIELD_STREACH * 0.5) point2 = self.convertToDrawWorld(x, -self.CW.FIELD_STREACH * 0.5) painter.drawLine(point1, point2) # draw defence arc sizeX = self.CW.FIELD_DEFENCE_RADIUS * 2.0 * self.scaleOnField sizeY = self.CW.FIELD_DEFENCE_RADIUS * 2.0 * self.scaleOnField rx = self.CW.PLAY_FIELD_WIDTH * 0.5 - self.CW.FIELD_DEFENCE_RADIUS ry = self.CW.FIELD_STREACH * 0.5 + self.CW.FIELD_DEFENCE_RADIUS rx *= self.scaleOnField ry *= self.scaleOnField ry *= -1.0 rect = QRectF(rx, ry, sizeX, sizeY) startAngle = 90 * 16 spanAngle = 90 * 16 painter.drawArc(rect, startAngle, spanAngle) ry = self.CW.FIELD_STREACH * 0.5 - self.CW.FIELD_DEFENCE_RADIUS ry *= self.scaleOnField rect = QRectF(rx, ry, sizeX, sizeY) startAngle = 180 * 16 spanAngle = 90 * 16 painter.drawArc(rect, startAngle, spanAngle) rx = -self.CW.FIELD_WIDTH - self.CW.FIELD_DEFENCE_RADIUS ry = self.CW.FIELD_STREACH * 0.5 + self.CW.FIELD_DEFENCE_RADIUS rx *= self.scaleOnField ry *= self.scaleOnField rect = QRectF(rx, ry, sizeX, sizeY) startAngle = 180 * 16 spanAngle = 90 * 16 painter.drawArc(rect, startAngle, spanAngle)
def boundingRect(self): return QRectF(0, 0, self._history_left + self._history_width + self._margin_right, self._history_bottom + self._margin_bottom)
def addGraph(self, graph_str): graph = graph_str.splitlines() header = graph[0].split() if header[0] != 'graph': raise Exception('wrong graph format', 'header is: ' + graph[0]) self.scale_factor = 100.0 self.width = float(header[2]) self.height = float(header[3]) print "QGraphicsScene size:", self.width, self.height self.scene = GraphScene( QRectF(0, 0, self.scX(self.width), self.scY(self.height))) for l in graph: items = l.split() if len(items) == 0: continue elif items[0] == 'stop': break elif items[0] == 'node': #node CImp 16.472 5.25 0.86659 0.5 CImp filled ellipse lightblue lightblue if len(items) != 11: raise Exception('wrong number of items in line', 'line is: ' + l) name = items[6] if name == "\"\"": name = "" w = self.scX(items[4]) h = self.scY(items[5]) x = self.tfX(items[2]) y = self.tfY(items[3]) self.nodes[name] = self.scene.addEllipse( x - w / 2, y - h / 2, w, h) self.nodes[name].setData(0, name) text_item = self.scene.addSimpleText(name) br = text_item.boundingRect() text_item.setPos(x - br.width() / 2, y - br.height() / 2) elif items[0] == 'edge': # without label: # edge CImp Ts 4 16.068 5.159 15.143 4.9826 12.876 4.5503 11.87 4.3583 solid black # # with label: # edge b_stSplit TorsoVelAggregate 7 7.5051 6.3954 7.7054 6.3043 7.9532 6.1899 8.1728 6.0833 8.4432 5.9522 8.7407 5.8012 8.9885 5.6735 aa 8.6798 5.9792 solid black line_len = int(items[3]) label_text = None label_pos = None if (line_len * 2 + 6) == len(items): # no label pass elif (line_len * 2 + 9) == len(items): # edge with label label_text = items[4 + line_len * 2] label_pos = QPointF(self.tfX(items[4 + line_len * 2 + 1]), self.tfY(items[4 + line_len * 2 + 2])) else: raise Exception( 'wrong number of items in line', 'should be: ' + str(line_len * 2 + 6) + " or " + str(line_len * 2 + 9) + ', line is: ' + l) line = [] for i in range(line_len): line.append((self.tfX(items[4 + i * 2]), self.tfY(items[5 + i * 2]))) control_points_idx = 1 path = QPainterPath(QPointF(line[0][0], line[0][1])) while True: q1 = line[control_points_idx] q2 = line[control_points_idx + 1] p2 = line[control_points_idx + 2] path.cubicTo(q1[0], q1[1], q2[0], q2[1], p2[0], p2[1]) control_points_idx = control_points_idx + 3 if control_points_idx >= len(line): break edge = self.scene.addPath(path) edge.setData(0, (items[1], items[2])) self.edges.append(edge) end_p = QPointF(line[-1][0], line[-1][1]) p0 = end_p - QPointF(line[-2][0], line[-2][1]) p0_norm = math.sqrt(p0.x() * p0.x() + p0.y() * p0.y()) p0 = p0 / p0_norm p0 = p0 * self.scale_factor * 0.15 p1 = QPointF(p0.y(), -p0.x()) * 0.25 p2 = -p1 poly = QPolygonF() poly.append(p0 + end_p) poly.append(p1 + end_p) poly.append(p2 + end_p) poly.append(p0 + end_p) # poly_path = QPainterPath() # poly_path.addPolygon(poly) # painter = QPainter() self.scene.addPolygon(poly) if label_text and label_pos: if label_text[0] == "\"": label_text = label_text[1:] if label_text[-1] == "\"": label_text = label_text[:-1] label_text = label_text.replace("\\n", "\n") label_item = self.scene.addSimpleText(label_text) br = label_item.boundingRect() label_item.setPos(label_pos.x() - br.width() / 2, label_pos.y() - br.height() / 2)