def draw_position(self, e): p = self.mapToScene(e.x(), e.y()) v = (p.x() - self.drag_start[0], p.y() - self.drag_start[1]) mag = sqrt(pow(v[0], 2) + pow(v[1], 2)) v = (v[0] / mag, v[1] / mag) # Normalize diff vector u = (-v[1], v[0]) # Project diff vector to mirrored map if self.last_path: self._scene.removeItem(self.last_path) self.last_path = None res = (v[0] * 25, v[1] * 25) if self._pose_mode: pen = QPen(QColor("red")) elif self._goal_mode: pen = QPen(QColor("green")) self.last_path = self._scene.addLine(self.drag_start[0], self.drag_start[1], self.drag_start[0] + res[0], self.drag_start[1] + res[1], pen) map_p = self.point_qt_to_map(self.drag_start) angle = atan2(u[0], u[1]) quat = quaternion_from_euler(0, 0, angle) self.drag_start = None return map_p, quat
def getComponentPen(state): b = QPen(QColor(0, 0, 255)) # unconfigured/preoperational if state == 'A': # stopped b = QPen(QBrush(QColor(255, 0, 0)), 5) elif state == 'N': # running b = QPen(QBrush(QColor(0, 0, 0)), 1) return b
def __init__(self, highlight_level, bounding_box, label, shape, color=None, parent=None, label_pos=None, tooltip=None): super(NodeItem, self).__init__(highlight_level, parent) self._default_color = self._COLOR_BLACK if color is None else color self._brush = QBrush(self._default_color) self._label_pen = QPen() self._label_pen.setColor(self._default_color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._ellipse_pen = QPen(self._label_pen) self._ellipse_pen.setWidth(1) self._incoming_edges = set() self._outgoing_edges = set() self.parse_shape(shape, bounding_box) self.addToGroup(self._graphics_item) self._label = QGraphicsSimpleTextItem(label) self._label.setFont(GraphItem._LABEL_FONT) label_rect = self._label.boundingRect() if label_pos is None: label_rect.moveCenter(bounding_box.center()) else: label_rect.moveCenter(label_pos) self._label.setPos(label_rect.x(), label_rect.y()) self.addToGroup(self._label) if tooltip is not None: self.setToolTip(tooltip) self.set_node_color() self.setAcceptHoverEvents(True) self.hovershape = None
def _draw_annotation(self, data): old_item = None if self.annotation_item: old_item = self.annotation_item annotation_item = None if not data == {}: resolution = self._drawing_objects['map'].info.resolution origin = self._drawing_objects['map'].info.origin w = self._drawing_objects['map'].info.width h = self._drawing_objects['map'].info.height x = -((data['x'] - origin.position.x) / resolution - w) y = (data['y'] - origin.position.y) / resolution if data['type'] == "yocs_msgs/Waypoint": #annotation_item = self._scene.addEllipse(x - (data['scale'][0] / resolution), y -(data['scale'][1] / resolution), data['scale'][0] / resolution * 2, data['scale'][1] / resolution * 2, pen=QPen(QColor(0, 0, 255)), brush=QBrush(QColor(0, 0, 255, 125))) viz_marker_pose = QMatrix().rotate(-data['yaw'] + 180).map( self._viz_marker_polygon).translated(x, y) annotation_item = self._scene.addPolygon( viz_marker_pose, pen=QPen(QColor(0, 0, 255)), brush=QBrush(QColor(0, 0, 255, 125))) elif data['type'] == "ar_track_alvar_msgs/AlvarMarker": viz_marker_pose = QMatrix().rotate( -(data['yaw'] - 90) + 180).map( self._viz_marker_polygon).translated(x, y) annotation_item = self._scene.addPolygon( viz_marker_pose, pen=QPen(QColor(0, 0, 255)), brush=QBrush(QColor(0, 0, 255, 125))) annotation_item.setZValue(2) if old_item: self._scene.removeItem(old_item) self.annotation_item = annotation_item
def paintEvent(self, event): geom = super(AxisWidget, self).geometry() h = geom.height() w = geom.width() box = QRect(2, 2, w - 4, h - 4) horiz = QLine(2, h / 2, w - 2, h / 2) vert = QLine(w / 2, 2, w / 2, h - 2) targ = QPoint(self._x * (w - 4) / 2 + w / 2, self._y * (h - 4) / 2 + h / 2) plt = super(AxisWidget, self).palette() linebrsh = plt.dark() targetbrsh = plt.highlight() linepen = QPen(linebrsh, 1, Qt.SolidLine, Qt.SquareCap) targetpen = QPen(targetbrsh, 2, Qt.SolidLine, Qt.SquareCap) qp = QPainter() qp.begin(self) qp.setPen(linepen) qp.drawRect(box) qp.drawLine(horiz) qp.drawLine(vert) qp.setPen(targetpen) qp.drawEllipse(targ, 10, 10) qp.end()
def paintEvent(self,event): super(JoystickPointView,self).paintEvent(event) try: if self._initialized: pass except: self._origPos = self.pos() self._initialized = True qp = QPainter() qp.begin(self) borderWidth = 2 radius = self.height()/2 center = QtCore.QPoint(self.height()/2,self.width()/2) # Outer Circle qp.setRenderHint(QPainter.Antialiasing, True) qp.setPen(QPen(QtCore.Qt.darkGray, borderWidth, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap,QtCore.Qt.RoundJoin)) qp.setBrush(QBrush(QtCore.Qt.white, QtCore.Qt.SolidPattern)) qp.drawEllipse(center,radius-borderWidth,radius-borderWidth) # Inner Circle qp.setPen(QPen(QtCore.Qt.lightGray, borderWidth, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap,QtCore.Qt.RoundJoin)) qp.setBrush(QBrush(QtCore.Qt.white, QtCore.Qt.SolidPattern)) qp.drawEllipse(center,radius-borderWidth-1,radius-borderWidth-1) qp.end()
def paint(self, painter, option, widget): painter.setFont(self._time_font) painter.fillRect(0, 0, SandtrayItem.length * SandtrayItem.scale, SandtrayItem.width * SandtrayItem.scale, painter.background()) for color, polys in self._zones.items(): painter.setPen(QPen(color, 2)) for poly in polys: painter.drawPolygon(QPolygonF(poly)) painter.setBrush(QBrush(self._fg_color)) painter.setPen(QPen(self._border_color, 1)) painter.drawRect(0, 0, SandtrayItem.length * SandtrayItem.scale, SandtrayItem.width * SandtrayItem.scale) for label, pos in self._items.items(): x, y = pos[0] * SandtrayItem.scale, pos[1] * SandtrayItem.scale painter.drawText(x - 10, y - 10, label) if "cube" in label: painter.setBrush(QBrush(self._cube_color)) painter.drawRect(x - 5, y - 5, 10, 10) else: painter.setBrush(QBrush(self._item_color)) painter.drawEllipse(QPointF(x, y), 10, 10)
def _draw_control_target(self, painter, color, robot): # ロボットの制御目標値を描画する # 経路の線を描画するための変数 prev_point = None robot_id = robot.robot_id target = self._control_targets[color][robot_id] # 経路を描画 for pose in target.path: point = self._convert_to_view(pose.x, pose.y) size = self._ROBOT_RADIUS * self._scale_field_to_view target_color = QColor(Qt.magenta) target_color.setAlphaF(0.5) painter.setPen(Qt.black) painter.setBrush(target_color) painter.drawEllipse(point, size, size) # 角度 line_x = self._ROBOT_RADIUS * math.cos(pose.theta) line_y = self._ROBOT_RADIUS * math.sin(pose.theta) line_point = point + self._convert_to_view(line_x, line_y) painter.drawLine(point, line_point) # IDを添える text_point = point + self._convert_to_view(self._ID_POS[0], self._ID_POS[1]) painter.drawText(text_point, str(robot_id)) # 経路を描画 if prev_point is None: prev_point = point else: painter.setPen(QPen(QColor(0, 0, 255, 127), 4)) painter.drawLine(prev_point, point) prev_point = point # キック・ドリブルフラグを、ロボットの現在位置周辺に描画 text_flag = "" if target.kick_power > 0.0: text_flag += "K:" + str(target.kick_power) if target.chip_enable is True: text_flag += "\nC:ON" if target.dribble_power > 0.0: text_flag += "\nD:" + str(target.dribble_power) point = self._convert_to_view(robot.pose.x, robot.pose.y) text_point = point + self._convert_to_view(self._FLAG_POS[0], self._FLAG_POS[1]) # 複数行に分けてテキストを描画するため、widthとheightを設定する text_width = 50 text_height = 100 painter.setPen(QPen(Qt.red, 2)) painter.drawText(text_point.x(), text_point.y(), text_width, text_height, 0, text_flag)
def __init__(self, bounding_box, shape, label, label_pos=None, url=None, parent=None, **kwargs): super(DmgHtmlNodeItem, self).__init__(parent, **kwargs) self.url = url self._incoming_edges = set() self._outgoing_edges = set() self._brush = QBrush(self._color) self._label_pen = QPen() self._label_pen.setColor(self._color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._label_pen.setWidthF(self._label_pen_width) self._graphics_item_pen = QPen(self._label_pen) self._graphics_item_pen.setWidthF(self._pen_width) self._label = QGraphicsTextItem() self._label.setHtml(label) label_rectangle = self._label.boundingRect() if label_pos is None: label_rectangle.moveCenter(bounding_box.center()) else: label_rectangle.moveCenter(label_pos) self._label.setPos(label_rectangle.x(), label_rectangle.y()) self.addToGroup(self._label) self._graphics_item = ShapeFactory.create(shape, bounding_box) if ShapeFactory.message is not None: print ShapeFactory.message self.addToGroup(self._graphics_item) self._brush.setColor(self._color) self._graphics_item_pen.setColor(self._color) self._label_pen.setColor(self._color) self._graphics_item.setPen(self._graphics_item_pen) self._highlight_level = kwargs.get('highlight_level', self.HIGHLIGHT_LEVEL) self._hovered_color = kwargs.get('hovered_color', self.HOVERED_COLOR) self._highlighted_color = kwargs.get('highlighted_color', self.HIGHLIGHTED_COLOR) self._highlighted_pen_width = kwargs.get('highlighted_pen_width', self.HIGHLIGHTED_PEN_WIDTH) self._highlighted_label_pen_width = kwargs.get( 'highlighted_label_pen_width', self.HIGHLIGHTED_LABEL_PEN_WIDTH) self.hover_shape = None self.setAcceptHoverEvents(True)
def on_qPixmapItemBottom_clicked(self, ev): radius = 10 pen = QPen(Qt.red, Qt.SolidPattern) pen.setWidth(5) qEllipse = self._qGraphicsSceneBottom.addEllipse(ev.pos().x() - radius, ev.pos().y() - radius, 2 * radius, 2 * radius, pen, QBrush()) self._qEllipseObjects.append(qEllipse) self._widget.pushButton_reset.setEnabled(True) self._widget.pushButton_send.setEnabled(True)
def __init__(self, parent): super(AngularLabel, self).__init__(parent) self.colorGreen = QColor(66, 255, 100, 128) self.colorRed = QColor(255, 66, 100, 128) self.brushGreen = QBrush(self.colorGreen) self.brushRed = QBrush(self.colorRed) self.penGreen = QPen(self.brushGreen, 1) self.penRed = QPen(self.brushRed, 1) self.setFixedSize(100, 100) self.angle = 0 self.velocity = 0
def __init__(self, mark_dim, view_dim): self.mark_dim = mark_dim self.view_dim = view_dim self._pens = { 'black': QPen(QtCore.Qt.black), 'white': QPen(QtCore.Qt.white) } self._brushes = { 'black': QBrush(QtCore.Qt.black), 'white': QBrush(QtCore.Qt.white) } self._prepare()
def __init__(self, bounding_box, shape, label, label_pos=None, url=None, parent=None, **kwargs): super(NodeItem, self).__init__(parent, **kwargs) self.url = url self._incoming_edges = set() self._outgoing_edges = set() self._brush = QBrush(self._color) self._label_pen = QPen() self._label_pen.setColor(self._color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._label_pen.setWidthF(self._label_pen_width) if self._pen_width == 0.0: self._graphics_item_pen = QPen(Qt.NoPen) else: self._graphics_item_pen = QPen(self._label_pen) self._graphics_item_pen.setWidthF(self._pen_width) self._graphics_item = ShapeFactory.create(shape, bounding_box) if ShapeFactory.message is not None: print ShapeFactory.message self.addToGroup(self._graphics_item) if not shape == 'point': self._label = QGraphicsSimpleTextItem(label) label_rectangle = self._label.boundingRect() if label_pos is None: label_rectangle.moveCenter(bounding_box.center()) else: label_rectangle.moveCenter(label_pos) self._label.setPos(label_rectangle.x(), label_rectangle.y()) self.addToGroup(self._label) else: self._graphics_item.setBrush(self._color) self._label = None self._brush.setColor(self._color) self._graphics_item_pen.setColor(self._color) self._label_pen.setColor(self._color) self._graphics_item.setPen(self._graphics_item_pen) if self._label is not None: self._label.setBrush(self._brush) self._label.setPen(self._label_pen)
def transitionSelected(self, index): for e in self.prev_selected_connections: e.setPen(QPen(QBrush(QColor(0, 0, 0)), 0)) self.prev_selected_connections = [] if not self.component_selected: return for e in self.edges: data = e.data(0) if (data[0] == self.component_selected) and ( data[1] == self.selected_component_next_states_names[index]): e.setPen(QPen(QBrush(QColor(255, 0, 0)), 5)) self.prev_selected_connections.append(e)
def paintEvent(self, event): with self.lock: self.event = event rect = event.rect() qp = QPainter() qp.begin(self) radius = min(rect.width(), rect.height()) - 50 qp.setFont(QFont('Helvetica', 100)) qp.setPen(QPen(QBrush(QColor(255, 255, 255)), 20)) if self.is_disabled: qp.fillRect(rect, self._DISABLED_COLOR) qp.drawText(rect, QtCore.Qt.AlignCenter, self._FROWN) elif self.is_blackout: qp.fillRect(rect, self._BLACKOUT_COLOR) qp.drawText(rect, QtCore.Qt.AlignCenter, self._FROWN) time_diff = (self.next_whiteout_time - rospy.Time.now()).to_sec() if time_diff < 0: time_diff = 0 time_ratio = time_diff / (self.next_whiteout_time - self.blackout_time).to_sec() qp.setFont(QFont('Helvetica', 30)) qp.drawText(0, rect.height() - 150, rect.width(), 150, QtCore.Qt.AlignCenter, "%.1f sec" % time_diff) # 0-360 if time_ratio > 0: rad = int(math.fmod(time_ratio * 360 + 90*16, 360) * 16) qp.drawArc((rect.width() - radius) / 2, (rect.height() - radius) / 2, radius, radius, 90*16, rad) else: qp.fillRect(rect, self._OK_COLOR) qp.drawText(rect, QtCore.Qt.AlignCenter, self._SMILEY) qp.end()
def addArrow(self, startPoint=QPointF(), endPoint=QPointF(), pen=QPen()): alpha = 5 * pi / 6 arrowLength = 10 theta = atan2((endPoint.y() - startPoint.y()), (endPoint.x() - startPoint.x())) gamma1 = theta + alpha gamma2 = theta - alpha arrowPoint_1 = QPointF(endPoint.x() + arrowLength * cos(gamma1), endPoint.y() + arrowLength * sin(gamma1)) arrowPoint_2 = QPointF(endPoint.x() + arrowLength * cos(gamma2), endPoint.y() + arrowLength * sin(gamma2)) line_0 = QLineF(startPoint, endPoint) line_1 = QLineF(endPoint, arrowPoint_1) line_2 = QLineF(endPoint, arrowPoint_2) line_item_0 = QGraphicsLineItem(line_0) line_item_0.setPen(pen) line_item_1 = QGraphicsLineItem(line_1) line_item_1.setPen(pen) line_item_2 = QGraphicsLineItem(line_2) line_item_2.setPen(pen) arrowItems = [line_item_0, line_item_1, line_item_2] self.addItem(line_item_0) self.addItem(line_item_1) self.addItem(line_item_2) return arrowItems
def paintEvent(self,event): if not self._initialized: self.placeStickAtCenter() self._initialized = True borderWidth = 1 joyRange = 80 center = QtCore.QPoint(self.height()/2,self.width()/2) qp = QPainter() qp.begin(self) qp.setRenderHint(QPainter.Antialiasing, True) qp.setPen(QPen(QtCore.Qt.lightGray, borderWidth, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap,QtCore.Qt.RoundJoin)) if self._mode == "circle": qp.drawEllipse(center,joyRange,joyRange) if self._mode == "square": x = center.x() - joyRange y = center.y() - joyRange width = joyRange * 2 height = joyRange * 2 qp.drawRect(x,y,width,height) qp.end() super(JoystickView,self).paintEvent(event)
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 _draw_playhead(self, painter): """ Draw a line and 2 triangles to denote the current position being viewed :param painter: ,''QPainter'' """ px = self.map_stamp_to_x(self.playhead.to_sec()) pw, ph = self._playhead_pointer_size # Line painter.setPen(QPen(self._playhead_color)) painter.setBrush(QBrush(self._playhead_color)) painter.drawLine(px, self._history_top - 1, px, self._history_bottom + 2) # Upper triangle py = self._history_top - ph painter.drawPolygon( QPolygonF([ QPointF(px, py + ph), QPointF(px + pw, py), QPointF(px - pw, py) ])) # Lower triangle py = self._history_bottom + 1 painter.drawPolygon( QPolygonF([ QPointF(px, py), QPointF(px + pw, py + ph), QPointF(px - pw, py + ph) ])) painter.setBrush(self._default_brush) painter.setPen(self._default_pen)
def drawAngleReplacement(self, painter): robot_pos = QPointF() if self._replace_is_friend: robot_pos.setX( self.friendOdoms[self._replace_id].pose.pose.position.x) robot_pos.setY( self.friendOdoms[self._replace_id].pose.pose.position.y) else: robot_pos.setX( self.enemyOdoms[self._replace_id].pose.pose.position.x) robot_pos.setY( self.enemyOdoms[self._replace_id].pose.pose.position.y) currentPos = self.convertToRealWorld(self._current_mouse_pos.x(), self._current_mouse_pos.y()) angle = math.degrees(self._to_angle(robot_pos, currentPos)) robotPoint = self.convertToDrawWorld(robot_pos.x(), robot_pos.y()) currentPoint = self.convertToDrawWorld(currentPos.x(), currentPos.y()) painter.setPen(QPen(Qt.blue, 2)) painter.drawLine(robotPoint, currentPoint) text = "[" + str(round(angle, 2)) + "]" painter.setPen(Qt.black) painter.drawText(currentPoint, text)
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_joy_target(self, painter): # JoyStickのControlTargetを描画する # 経路の線を描画するための変数 prev_point = None for i, pose in enumerate(self._joy_target.path): point = self._convert_to_view(pose.x, pose.y) size = self._ROBOT_RADIUS * self._scale_field_to_view joy_color = QColor(Qt.magenta) painter.setPen(Qt.black) painter.setBrush(joy_color) painter.drawEllipse(point, size, size) # 角度 line_x = self._ROBOT_RADIUS * math.cos(pose.theta) line_y = self._ROBOT_RADIUS * math.sin(pose.theta) line_point = point + self._convert_to_view(line_x, line_y) painter.drawLine(point, line_point) # インデックス text_point = point + self._convert_to_view(self._ID_POS[0], self._ID_POS[1]) painter.drawText(text_point, str(i)) # 経路を描画 if prev_point is None: prev_point = point else: painter.setPen(QPen(QColor(0, 0, 255, 127), 4)) painter.drawLine(prev_point, point) prev_point = point
def __init__(self, scene, time, color=None): y2 = len(scene._tracks) * TimelineTrack.height super(TimelineMarker, self).__init__(time, - TimelineTrack.height, time, y2, None, scene) self.setZValue(self._z) if color is None: color = QColor(self._default_color) color.setAlphaF(0.5) self.setPen(QPen(QBrush(color), 0.05))
def draw_viz_markers(self, data, key): old_items = [] if len(self._viz_marker_items[key]): for item in self._viz_marker_items[key]: old_items.append(item) self._viz_marker_items[key] = [] for viz_marker in data: if viz_marker['type'] is Marker.TEXT_VIEW_FACING: # text viz_marker_text = viz_marker['text'] viz_marker_pose_item = self._scene.addSimpleText( viz_marker_text, font=QFont()) # Everything must be mirrored viz_marker_pose_item.translate(-viz_marker['x'], viz_marker['y']) elif viz_marker['type'] is Marker.CYLINDER: # # waypoint # viz_marker_pose_item = self._scene.addEllipse(viz_marker['x'] - viz_marker['scale'][0] / 2, viz_marker['y'] - viz_marker['scale'][1] / 2, viz_marker['scale'][0], viz_marker['scale'][1], pen=QPen(QColor(255, 0, 0)), brush=QBrush(QColor(255, 0, 0))) # # Everything must be mirrored # self._mirror(viz_marker_pose_item) viz_marker_pose = QMatrix().scale( 1, -1).rotate(viz_marker['yaw'] + 180).map( self._viz_marker_polygon).translated( -viz_marker['x'], viz_marker['y']) viz_marker_pose_item = self._scene.addPolygon( viz_marker_pose, pen=QPen(QColor(0, 255, 0)), brush=QBrush(QColor(0, 255, 0))) elif viz_marker['type'] is Marker.ARROW: # marker # Everything must be mirrored viz_marker_pose = QMatrix().scale( 1, -1).rotate((viz_marker['yaw'] - 90) + 180).map( self._viz_marker_polygon).translated( -viz_marker['x'], viz_marker['y']) viz_marker_pose_item = self._scene.addPolygon( viz_marker_pose, pen=QPen(QColor(255, 0, 0)), brush=QBrush(QColor(255, 0, 0))) else: rospy.logerr("Unknown Marker type : %s" % (viz_marker['type'])) viz_marker_pose_item.setZValue(1) self._viz_marker_items[key].append(viz_marker_pose_item) if len(old_items): for item in old_items: self._scene.removeItem(item)
def __init__(self, bounding_box, shape, label, label_pos=None, url=None, parent=None, **kwargs): super(DmgHtmlNodeItem, self).__init__(parent, **kwargs) self.url = url self._incoming_edges = set() self._outgoing_edges = set() self._brush = QBrush(self._color) self._label_pen = QPen() self._label_pen.setColor(self._color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._label_pen.setWidthF(self._label_pen_width) self._graphics_item_pen = QPen(self._label_pen) self._graphics_item_pen.setWidthF(self._pen_width) self._label = QGraphicsTextItem() self._label.setHtml(label) label_rectangle = self._label.boundingRect() if label_pos is None: label_rectangle.moveCenter(bounding_box.center()) else: label_rectangle.moveCenter(label_pos) self._label.setPos(label_rectangle.x(), label_rectangle.y()) self.addToGroup(self._label) self._graphics_item = ShapeFactory.create(shape, bounding_box) if ShapeFactory.message is not None: print ShapeFactory.message self.addToGroup(self._graphics_item) self._brush.setColor(self._color) self._graphics_item_pen.setColor(self._color) self._label_pen.setColor(self._color) self._graphics_item.setPen(self._graphics_item_pen) self._highlight_level = kwargs.get('highlight_level', self.HIGHLIGHT_LEVEL) self._hovered_color = kwargs.get('hovered_color', self.HOVERED_COLOR) self._highlighted_color = kwargs.get('highlighted_color', self.HIGHLIGHTED_COLOR) self._highlighted_pen_width = kwargs.get('highlighted_pen_width', self.HIGHLIGHTED_PEN_WIDTH) self._highlighted_label_pen_width = kwargs.get('highlighted_label_pen_width', self.HIGHLIGHTED_LABEL_PEN_WIDTH) self.hover_shape = None self.setAcceptHoverEvents(True)
def portSelected(self, index): for e in self.prev_selected_connections: e.setPen(QPen(QBrush(QColor(0, 0, 0)), 0)) self.prev_selected_connections = [] if not self.component_selected: return for conn in self.parent.all_connections: if (conn[0] == self.component_selected and conn[1] == self.selected_component_port_names[index]) or \ (conn[2] == self.component_selected and conn[3] == self.selected_component_port_names[index]): for graph_name in self.edges: for e in self.edges[graph_name]: data = e.data(0) if (data[0] == conn[0] and data[1] == conn[2]) or \ (data[0] == conn[2] and data[1] == conn[0]): e.setPen(QPen(QBrush(QColor(255, 0, 0)), 5)) self.prev_selected_connections.append(e)
def _update_path(self, name): old_item = None if name in self._paths.keys(): old_item = self._paths[name].item self._paths[name].item = self._scene.addPath( self._paths[name].path, pen=QPen(QColor(*self._paths[name].color))) if old_item: self._scene.removeItem(old_item)
def paint(self, painter, option, index): is_dark = True item = self.parent().item(index.row()) if item.faulty: pen = QPen(QColor(255, 117, 117), 3) painter.setPen(pen) painter.drawRect(option.rect) elif item == self.parent().currentItem(): pen = QPen(Qt.white, 3) painter.setPen(pen) painter.drawRect(option.rect) if not item.has_script: painter.fillRect(option.rect, QColor(153, 153, 153)) else: painter.fillRect(option.rect, Qt.white) is_dark = False doc = QTextDocument() highlight = syntax.PythonHighlighter(doc, is_dark = is_dark) font = QFont("Courier") font.setFamily("Courier"); font.setStyleHint(QFont.Monospace); font.setFixedPitch(True); font.setPointSize(self.parent().font().pointSize()) doc.setDefaultFont(font) text = index.data(Qt.EditRole) text = text.replace("\t", ''.join([' '] * 4)) doc.setPlainText(text) doc.setDefaultStyleSheet("background-color: red;") painter.translate(option.rect.topLeft()) doc.drawContents(painter) painter.resetTransform()
def drawPosReplacement(self, painter): startPos = self.convertToRealWorld( self.clickPoint.x(), self.clickPoint.y()) currentPos = self.convertToRealWorld( self._current_mouse_pos.x(), self._current_mouse_pos.y()) startPoint = self.convertToDrawWorld(startPos.x(), startPos.y()) currentPoint = self.convertToDrawWorld(currentPos.x(), currentPos.y()) painter.setPen(QPen(Qt.red,2)) painter.drawLine(startPoint, currentPoint)
def add_curve(self, curve_id, curve_name, curve_color=QColor(Qt.blue), markers_on=False): curve_id = str(curve_id) if curve_id in self._curves: return curve_object = Qwt.QwtPlotCurve(curve_name) curve_object.attach(self) curve_object.setPen(curve_color) if markers_on: curve_object.setSymbol( Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse, QBrush(curve_color), QPen(Qt.black), QSize(4, 4))) self._curves[curve_id] = curve_object
def __init__(self, *args): super(QwtDataPlot, self).__init__(*args) self.setCanvasBackground(Qt.white) self.insertLegend(Qwt.QwtLegend(), Qwt.QwtPlot.BottomLegend) self._curves = {} # TODO: rejigger these internal data structures so that they're easier # to work with, and easier to use with set_xlim and set_ylim # this may also entail rejiggering the _time_axis so that it's # actually time axis data, or just isn't required any more # new data structure self._x_limits = [0.0, 10.0] self._y_limits = [0.0, 10.0] # old data structures self._last_canvas_x = 0 self._last_canvas_y = 0 self._pressed_canvas_y = 0 self._pressed_canvas_x = 0 self._last_click_coordinates = None marker_axis_y = Qwt.QwtPlotMarker() marker_axis_y.setLabelAlignment(Qt.AlignRight | Qt.AlignTop) marker_axis_y.setLineStyle(Qwt.QwtPlotMarker.HLine) marker_axis_y.setYValue(0.0) marker_axis_y.attach(self) self._picker = Qwt.QwtPlotPicker(Qwt.QwtPlot.xBottom, Qwt.QwtPlot.yLeft, Qwt.QwtPicker.PolygonSelection, Qwt.QwtPlotPicker.PolygonRubberBand, Qwt.QwtPicker.AlwaysOn, self.canvas()) self._picker.setRubberBandPen(QPen(Qt.blue)) self._picker.setTrackerPen(QPen(Qt.blue)) # Initialize data self.rescale() #self.move_canvas(0, 0) self.canvas().setMouseTracking(True) self.canvas().installEventFilter(self)
def _draw_pos_replacement(self, painter): # 位置のReplacementを描画する start_pos = self._convert_to_field(self._click_point.x(), self._click_point.y()) current_pos = self._convert_to_field(self._current_mouse_pos.x(), self._current_mouse_pos.y()) start_point = self._convert_to_view(start_pos.x(), start_pos.y()) current_point = self._convert_to_view(current_pos.x(), current_pos.y()) painter.setPen(QPen(Qt.red, 2)) painter.drawLine(start_point, current_point)
def __init__(self, *args): super(QwtDataPlot, self).__init__(*args) self.setCanvasBackground(Qt.white) self.insertLegend(Qwt.QwtLegend(), Qwt.QwtPlot.BottomLegend) self._curves = {} self._data_offset_x = 0 self._canvas_offset_x = 0 self._canvas_offset_y = 0 self._last_canvas_x = 0 self._last_canvas_y = 0 self._pressed_canvas_y = 0 self._last_click_coordinates = None self._color_index = 0 self._autoscroll = False marker_axis_y = Qwt.QwtPlotMarker() marker_axis_y.setLabelAlignment(Qt.AlignRight | Qt.AlignTop) marker_axis_y.setLineStyle(Qwt.QwtPlotMarker.HLine) marker_axis_y.setYValue(0.0) marker_axis_y.attach(self) self._picker = Qwt.QwtPlotPicker(Qwt.QwtPlot.xBottom, Qwt.QwtPlot.yLeft, Qwt.QwtPicker.PolygonSelection, Qwt.QwtPlotPicker.PolygonRubberBand, Qwt.QwtPicker.AlwaysOn, self.canvas()) self._picker.setRubberBandPen(QPen(self._colors[-1])) self._picker.setTrackerPen(QPen(self._colors[-1])) # Initialize data self._time_axis = arange(self._num_values_ploted) self._canvas_display_height = 1000 self._canvas_display_width = self.canvas().width() self._data_offset_x = self._num_value_saved - len(self._time_axis) self.redraw() self.move_canvas(0, 0) self.canvas().setMouseTracking(True) self.canvas().installEventFilter(self)
def paint(self, painter, option, widget): """Overwrites BlockItem.paint so that we can fill in the block rectangles""" brush = QBrush() brush.setStyle(Qt.SolidPattern) brush.setColor(self.bgcolor) painter.fillRect(self.rect(), brush) border_pen = QPen() border_pen.setBrush(self.border_color) border_pen.setStyle(Qt.SolidLine) border_pen.setWidth(self.border_width) painter.setPen(border_pen) painter.drawRect(self.rect())
def __init__(self, highlight_level, bounding_box, label, shape, color=None, parent=None, label_pos=None, tooltip=None): super(NodeItem, self).__init__(highlight_level, parent) self._default_color = self._COLOR_BLACK if color is None else color self._brush = QBrush(self._default_color) self._label_pen = QPen() self._label_pen.setColor(self._default_color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._ellipse_pen = QPen(self._label_pen) self._ellipse_pen.setWidth(1) self._incoming_edges = set() self._outgoing_edges = set() if shape == 'box': self._graphics_item = QGraphicsRectItem(bounding_box) else: self._graphics_item = QGraphicsEllipseItem(bounding_box) self.addToGroup(self._graphics_item) self._label = QGraphicsSimpleTextItem(label) label_rect = self._label.boundingRect() if label_pos is None: label_rect.moveCenter(bounding_box.center()) else: label_rect.moveCenter(label_pos) self._label.setPos(label_rect.x(), label_rect.y()) self.addToGroup(self._label) if tooltip is not None: self.setToolTip(tooltip) self.set_node_color() self.setAcceptHoverEvents(True) self.hovershape = None
def paint(self, painter, option, widget): # Paint background brush = QBrush() brush.setStyle(Qt.SolidPattern) brush.setColor(self.bgcolor) painter.fillRect(self.rect(), brush) # Paint border border_pen = QPen() border_pen.setBrush(self.border_color) border_pen.setStyle(Qt.SolidLine) border_pen.setWidth(self.border_width) painter.setPen(border_pen) painter.drawRect(self.rect()) rect = self.geometry() # Create arrows arrow_scale = 0.25 arrow_width = rect.width() * arrow_scale arrow_height = arrow_width * 0.8 arrow_margin = (rect.width() - arrow_width) / 2.0 brush.setColor(self.label_color) painter.setPen(Qt.NoPen) painter.setBrush(brush) arrow = None if self.topBand == self.dest_band_item: # Draw pointing up arrow = QPolygon([QPoint(0, arrow_height), QPoint(arrow_width, arrow_height), QPoint(arrow_width / 2.0, 0)]) arrow.translate(self.rect().x() + arrow_margin, self.rect().y() + 1) else: # Draw pointing down arrow = QPolygon([QPoint(0, 0), QPoint(arrow_width, 0), QPoint(arrow_width / 2.0, arrow_height)]) arrow.translate(self.rect().x() + arrow_margin, self.rect().y() + rect.height() - arrow_height) painter.drawPolygon(arrow) # Label painter.setPen(self.label_color) painter.rotate(-90) fm = painter.fontMetrics() elided = fm.elidedText(self.label, Qt.ElideRight, rect.height()) twidth = fm.width(elided) painter.drawText(-twidth - (rect.height() - twidth) / 2, rect.width() - 2, elided)
def paint(self, painter, option, widget): # Paint background brush = QBrush() brush.setStyle(Qt.SolidPattern) brush.setColor(self.bgcolor) painter.fillRect(self.rect(), brush) # Paint border border_pen = QPen() border_pen.setBrush(self.border_color) border_pen.setStyle(Qt.SolidLine) border_pen.setWidth(self.border_width) painter.setPen(border_pen) painter.drawRect(self.rect()) rect = self.geometry() # Create arrows arrow_scale = 0.25 arrow_width = rect.width() * arrow_scale arrow_height = arrow_width * 0.8 arrow_margin = (rect.width() - arrow_width) / 2.0 brush.setColor(self.label_color) painter.setPen(Qt.NoPen) painter.setBrush(brush)
class DmgHtmlNodeItem(GraphItem): HIGHLIGHT_LEVEL = 1 HOVERED_COLOR = QColor(250, 0, 0) HIGHLIGHTED_COLOR = QColor(100, 100, 100) HIGHLIGHTED_PEN_WIDTH = 2.0 HIGHLIGHTED_LABEL_PEN_WIDTH = 1.0 def __init__(self, bounding_box, shape, label, label_pos=None, url=None, parent=None, **kwargs): super(DmgHtmlNodeItem, self).__init__(parent, **kwargs) self.url = url self._incoming_edges = set() self._outgoing_edges = set() self._brush = QBrush(self._color) self._label_pen = QPen() self._label_pen.setColor(self._color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._label_pen.setWidthF(self._label_pen_width) self._graphics_item_pen = QPen(self._label_pen) self._graphics_item_pen.setWidthF(self._pen_width) self._label = QGraphicsTextItem() self._label.setHtml(label) label_rectangle = self._label.boundingRect() if label_pos is None: label_rectangle.moveCenter(bounding_box.center()) else: label_rectangle.moveCenter(label_pos) self._label.setPos(label_rectangle.x(), label_rectangle.y()) self.addToGroup(self._label) self._graphics_item = ShapeFactory.create(shape, bounding_box) if ShapeFactory.message is not None: print ShapeFactory.message self.addToGroup(self._graphics_item) self._brush.setColor(self._color) self._graphics_item_pen.setColor(self._color) self._label_pen.setColor(self._color) self._graphics_item.setPen(self._graphics_item_pen) self._highlight_level = kwargs.get('highlight_level', self.HIGHLIGHT_LEVEL) self._hovered_color = kwargs.get('hovered_color', self.HOVERED_COLOR) self._highlighted_color = kwargs.get('highlighted_color', self.HIGHLIGHTED_COLOR) self._highlighted_pen_width = kwargs.get('highlighted_pen_width', self.HIGHLIGHTED_PEN_WIDTH) self._highlighted_label_pen_width = kwargs.get('highlighted_label_pen_width', self.HIGHLIGHTED_LABEL_PEN_WIDTH) self.hover_shape = None self.setAcceptHoverEvents(True) def add_incoming_edge(self, edge): self._incoming_edges.add(edge) def add_outgoing_edge(self, edge): self._outgoing_edges.add(edge) def set_color(self, color=None): if color is None: color = self._color self._brush.setColor(color) self._graphics_item_pen.setColor(color) self._label.setDefaultTextColor(color) self._graphics_item.setPen(self._graphics_item_pen) def set_hover_shape(self, shape): self.hover_shape = shape def shape(self): if self.hover_shape is not None: path = QPainterPath() path.addRect(self.hover_shape) return path return super(GraphItem, self).shape() def hoverEnterEvent(self, event): self.set_color(self._highlighted_color) self._highlight_connections() def hoverLeaveEvent(self, event): self.set_color() self._highlight_connections(False) def _highlight_connections(self, highlighted=True): if highlighted: if self._highlight_level > 1: cyclic_edges = self._incoming_edges.intersection(self._outgoing_edges) # incoming edges in blue incoming_nodes = set() for incoming_edge in self._incoming_edges.difference(cyclic_edges): incoming_edge.set_color(self.COLOR_BLUE) if incoming_edge.from_node != self: incoming_nodes.add(incoming_edge.from_node) # outgoing edges in green outgoing_nodes = set() for outgoing_edge in self._outgoing_edges.difference(cyclic_edges): outgoing_edge.set_color(self.COLOR_GREEN) if outgoing_edge.to_node != self: outgoing_nodes.add(outgoing_edge.to_node) # incoming/outgoing edges in teal for edge in cyclic_edges: edge.set_color(self.COLOR_TEAL) if self._highlight_level > 2: cyclic_nodes = incoming_nodes.intersection(outgoing_nodes) # incoming nodes in blue for incoming_node in incoming_nodes.difference(cyclic_nodes): incoming_node.set_color(self.COLOR_BLUE) # outgoing nodes in green for outgoing_node in outgoing_nodes.difference(cyclic_nodes): outgoing_node.set_color(self.COLOR_GREEN) # incoming/outgoing nodes in teal for node in cyclic_nodes: node.set_color(self.COLOR_TEAL) else: if self._highlight_level > 1: for incoming_edge in self._incoming_edges: incoming_edge.set_color() if self.highlight_level > 2 and incoming_edge.from_node != self: incoming_edge.from_node.set_color() for outgoing_edge in self._outgoing_edges: outgoing_edge.set_color() if self.highlight_level > 2 and outgoing_edge.to_node != self: outgoing_edge.to_node.set_color() def highlight(self, highlighted=True): if highlighted: self._graphics_item_pen.setWidthF(self._highlighted_pen_width) else: self._graphics_item_pen.setWidthF(self._pen_width) self._graphics_item.setPen(self._graphics_item_pen)
def __init__(self, highlight_level, spline, label_center, label, from_node, to_node, parent=None, penwidth=1, edge_color=None, style='solid'): super(EdgeItem, self).__init__(highlight_level, parent) self.from_node = from_node self.from_node.add_outgoing_edge(self) self.to_node = to_node self.to_node.add_incoming_edge(self) self._default_edge_color = self._COLOR_BLACK if edge_color is not None: self._default_edge_color = edge_color self._default_text_color = self._COLOR_BLACK self._default_color = self._COLOR_BLACK self._text_brush = QBrush(self._default_color) self._shape_brush = QBrush(self._default_color) if style in ['dashed', 'dotted']: self._shape_brush = QBrush(Qt.transparent) self._label_pen = QPen() self._label_pen.setColor(self._default_text_color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._edge_pen = QPen(self._label_pen) self._edge_pen.setWidth(penwidth) self._edge_pen.setColor(self._default_edge_color) self._edge_pen.setStyle(self._qt_pen_styles.get(style, Qt.SolidLine)) self._sibling_edges = set() self._label = None if label is not None: self._label = QGraphicsSimpleTextItem(label) label_rect = self._label.boundingRect() label_rect.moveCenter(label_center) self._label.setPos(label_rect.x(), label_rect.y()) self._label.hoverEnterEvent = self._handle_hoverEnterEvent self._label.hoverLeaveEvent = self._handle_hoverLeaveEvent self._label.setAcceptHoverEvents(True) # spline specification according to http://www.graphviz.org/doc/info/attrs.html#k:splineType coordinates = spline.split(' ') # extract optional end_point end_point = None if (coordinates[0].startswith('e,')): parts = coordinates.pop(0)[2:].split(',') end_point = QPointF(float(parts[0]), -float(parts[1])) # extract optional start_point if (coordinates[0].startswith('s,')): parts = coordinates.pop(0).split(',') # first point parts = coordinates.pop(0).split(',') point = QPointF(float(parts[0]), -float(parts[1])) path = QPainterPath(point) while len(coordinates) > 2: # extract triple of points for a cubic spline parts = coordinates.pop(0).split(',') point1 = QPointF(float(parts[0]), -float(parts[1])) parts = coordinates.pop(0).split(',') point2 = QPointF(float(parts[0]), -float(parts[1])) parts = coordinates.pop(0).split(',') point3 = QPointF(float(parts[0]), -float(parts[1])) path.cubicTo(point1, point2, point3) self._arrow = None if end_point is not None: # draw arrow self._arrow = QGraphicsPolygonItem() polygon = QPolygonF() polygon.append(point3) offset = QPointF(end_point - point3) corner1 = QPointF(-offset.y(), offset.x()) * 0.35 corner2 = QPointF(offset.y(), -offset.x()) * 0.35 polygon.append(point3 + corner1) polygon.append(end_point) polygon.append(point3 + corner2) self._arrow.setPolygon(polygon) self._arrow.hoverEnterEvent = self._handle_hoverEnterEvent self._arrow.hoverLeaveEvent = self._handle_hoverLeaveEvent self._arrow.setAcceptHoverEvents(True) self._path = QGraphicsPathItem() self._path.setPath(path) self.addToGroup(self._path) self.set_node_color() self.set_label_color()
class EdgeItem(GraphItem): _qt_pen_styles = { 'dashed': Qt.DashLine, 'dotted': Qt.DotLine, 'solid': Qt.SolidLine, } def __init__(self, highlight_level, spline, label_center, label, from_node, to_node, parent=None, penwidth=1, edge_color=None, style='solid'): super(EdgeItem, self).__init__(highlight_level, parent) self.from_node = from_node self.from_node.add_outgoing_edge(self) self.to_node = to_node self.to_node.add_incoming_edge(self) self._default_edge_color = self._COLOR_BLACK if edge_color is not None: self._default_edge_color = edge_color self._default_text_color = self._COLOR_BLACK self._default_color = self._COLOR_BLACK self._text_brush = QBrush(self._default_color) self._shape_brush = QBrush(self._default_color) if style in ['dashed', 'dotted']: self._shape_brush = QBrush(Qt.transparent) self._label_pen = QPen() self._label_pen.setColor(self._default_text_color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._edge_pen = QPen(self._label_pen) self._edge_pen.setWidth(penwidth) self._edge_pen.setColor(self._default_edge_color) self._edge_pen.setStyle(self._qt_pen_styles.get(style, Qt.SolidLine)) self._sibling_edges = set() self._label = None if label is not None: self._label = QGraphicsSimpleTextItem(label) label_rect = self._label.boundingRect() label_rect.moveCenter(label_center) self._label.setPos(label_rect.x(), label_rect.y()) self._label.hoverEnterEvent = self._handle_hoverEnterEvent self._label.hoverLeaveEvent = self._handle_hoverLeaveEvent self._label.setAcceptHoverEvents(True) # spline specification according to http://www.graphviz.org/doc/info/attrs.html#k:splineType coordinates = spline.split(' ') # extract optional end_point end_point = None if (coordinates[0].startswith('e,')): parts = coordinates.pop(0)[2:].split(',') end_point = QPointF(float(parts[0]), -float(parts[1])) # extract optional start_point if (coordinates[0].startswith('s,')): parts = coordinates.pop(0).split(',') # first point parts = coordinates.pop(0).split(',') point = QPointF(float(parts[0]), -float(parts[1])) path = QPainterPath(point) while len(coordinates) > 2: # extract triple of points for a cubic spline parts = coordinates.pop(0).split(',') point1 = QPointF(float(parts[0]), -float(parts[1])) parts = coordinates.pop(0).split(',') point2 = QPointF(float(parts[0]), -float(parts[1])) parts = coordinates.pop(0).split(',') point3 = QPointF(float(parts[0]), -float(parts[1])) path.cubicTo(point1, point2, point3) self._arrow = None if end_point is not None: # draw arrow self._arrow = QGraphicsPolygonItem() polygon = QPolygonF() polygon.append(point3) offset = QPointF(end_point - point3) corner1 = QPointF(-offset.y(), offset.x()) * 0.35 corner2 = QPointF(offset.y(), -offset.x()) * 0.35 polygon.append(point3 + corner1) polygon.append(end_point) polygon.append(point3 + corner2) self._arrow.setPolygon(polygon) self._arrow.hoverEnterEvent = self._handle_hoverEnterEvent self._arrow.hoverLeaveEvent = self._handle_hoverLeaveEvent self._arrow.setAcceptHoverEvents(True) self._path = QGraphicsPathItem() self._path.setPath(path) self.addToGroup(self._path) self.set_node_color() self.set_label_color() def add_to_scene(self, scene): scene.addItem(self) if self._label is not None: scene.addItem(self._label) if self._arrow is not None: scene.addItem(self._arrow) def setToolTip(self, tool_tip): super(EdgeItem, self).setToolTip(tool_tip) if self._label is not None: self._label.setToolTip(tool_tip) if self._arrow is not None: self._arrow.setToolTip(tool_tip) def add_sibling_edge(self, edge): self._sibling_edges.add(edge) def set_node_color(self, color=None): if color is None: self._label_pen.setColor(self._default_text_color) self._text_brush.setColor(self._default_color) if self._shape_brush.isOpaque(): self._shape_brush.setColor(self._default_color) self._edge_pen.setColor(self._default_edge_color) else: self._label_pen.setColor(color) self._text_brush.setColor(color) if self._shape_brush.isOpaque(): self._shape_brush.setColor(color) self._edge_pen.setColor(color) self._path.setPen(self._edge_pen) if self._arrow is not None: self._arrow.setBrush(self._shape_brush) self._arrow.setPen(self._edge_pen) def set_label_color(self, color=None): if color is None: self._label_pen.setColor(self._default_text_color) else: self._label_pen.setColor(color) if self._label is not None: self._label.setBrush(self._text_brush) self._label.setPen(self._label_pen) def _handle_hoverEnterEvent(self, event): # hovered edge item in red self.set_node_color(self._COLOR_RED) if self._highlight_level > 1: if self.from_node != self.to_node: # from-node in blue self.from_node.set_node_color(self._COLOR_BLUE) # to-node in green self.to_node.set_node_color(self._COLOR_GREEN) else: # from-node/in-node in teal self.from_node.set_node_color(self._COLOR_TEAL) self.to_node.set_node_color(self._COLOR_TEAL) if self._highlight_level > 2: # sibling edges in orange for sibling_edge in self._sibling_edges: sibling_edge.set_node_color(self._COLOR_ORANGE) def _handle_hoverLeaveEvent(self, event): self.set_node_color() if self._highlight_level > 1: self.from_node.set_node_color() self.to_node.set_node_color() if self._highlight_level > 2: for sibling_edge in self._sibling_edges: sibling_edge.set_node_color()
class NodeItem(GraphItem): def __init__(self, highlight_level, bounding_box, label, shape, color=None, parent=None, label_pos=None, tooltip=None): super(NodeItem, self).__init__(highlight_level, parent) self._default_color = self._COLOR_BLACK if color is None else color self._brush = QBrush(self._default_color) self._label_pen = QPen() self._label_pen.setColor(self._default_color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._ellipse_pen = QPen(self._label_pen) self._ellipse_pen.setWidth(1) self._incoming_edges = set() self._outgoing_edges = set() if shape == 'box': self._graphics_item = QGraphicsRectItem(bounding_box) else: self._graphics_item = QGraphicsEllipseItem(bounding_box) self.addToGroup(self._graphics_item) self._label = QGraphicsSimpleTextItem(label) label_rect = self._label.boundingRect() if label_pos is None: label_rect.moveCenter(bounding_box.center()) else: label_rect.moveCenter(label_pos) self._label.setPos(label_rect.x(), label_rect.y()) self.addToGroup(self._label) if tooltip is not None: self.setToolTip(tooltip) self.set_node_color() self.setAcceptHoverEvents(True) self.hovershape = None def set_hovershape(self, newhovershape): self.hovershape = newhovershape def shape(self): if self.hovershape is not None: path = QPainterPath() path.addRect(self.hovershape) return path else: return super(self.__class__, self).shape() def add_incoming_edge(self, edge): self._incoming_edges.add(edge) def add_outgoing_edge(self, edge): self._outgoing_edges.add(edge) def set_node_color(self, color=None): if color is None: color = self._default_color self._brush.setColor(color) self._ellipse_pen.setColor(color) self._label_pen.setColor(color) self._graphics_item.setPen(self._ellipse_pen) self._label.setBrush(self._brush) self._label.setPen(self._label_pen) def hoverEnterEvent(self, event): # hovered node item in red self.set_node_color(self._COLOR_RED) if self._highlight_level > 1: cyclic_edges = self._incoming_edges.intersection(self._outgoing_edges) # incoming edges in blue incoming_nodes = set() for incoming_edge in self._incoming_edges.difference(cyclic_edges): incoming_edge.set_node_color(self._COLOR_BLUE) if incoming_edge.from_node != self: incoming_nodes.add(incoming_edge.from_node) # outgoing edges in green outgoing_nodes = set() for outgoing_edge in self._outgoing_edges.difference(cyclic_edges): outgoing_edge.set_node_color(self._COLOR_GREEN) if outgoing_edge.to_node != self: outgoing_nodes.add(outgoing_edge.to_node) # incoming/outgoing edges in teal for edge in cyclic_edges: edge.set_node_color(self._COLOR_TEAL) if self._highlight_level > 2: cyclic_nodes = incoming_nodes.intersection(outgoing_nodes) # incoming nodes in blue for incoming_node in incoming_nodes.difference(cyclic_nodes): incoming_node.set_node_color(self._COLOR_BLUE) # outgoing nodes in green for outgoing_node in outgoing_nodes.difference(cyclic_nodes): outgoing_node.set_node_color(self._COLOR_GREEN) # incoming/outgoing nodes in teal for node in cyclic_nodes: node.set_node_color(self._COLOR_TEAL) def hoverLeaveEvent(self, event): self.set_node_color() if self._highlight_level > 1: for incoming_edge in self._incoming_edges: incoming_edge.set_node_color() if self._highlight_level > 2 and incoming_edge.from_node != self: incoming_edge.from_node.set_node_color() for outgoing_edge in self._outgoing_edges: outgoing_edge.set_node_color() if self._highlight_level > 2 and outgoing_edge.to_node != self: outgoing_edge.to_node.set_node_color()
def __init__(self, spline, label, label_center, from_node, to_node, parent=None, **kwargs): super(EdgeItem, self).__init__(parent, **kwargs) self._edge_pen_width = kwargs.get('edge_pen_width', self.EDGE_PEN_WIDTH) self.from_node = from_node self.from_node.add_outgoing_edge(self) self.to_node = to_node self.to_node.add_incoming_edge(self) self._brush = QBrush(self._color) self._label_pen = QPen() self._label_pen.setColor(self._color) self._label_pen.setJoinStyle(Qt.RoundJoin) self._label_pen.setWidthF(self._label_pen_width) self._edge_pen = QPen() self._edge_pen.setColor(self._color) self._edge_pen.setWidthF(self._edge_pen_width) self._sibling_edges = set() self._label = None if label is not None: self._label = QGraphicsSimpleTextItem(label) font = self._label.font() font.setPointSize(8) self._label.setFont(font) label_rect = self._label.boundingRect() label_rect.moveCenter(label_center) self._label.setPos(label_rect.x(), label_rect.y()) # spline specification according to http://www.graphviz.org/doc/info/attrs.html#k:splineType coordinates = spline.split(' ') # extract optional end_point end_point = None if coordinates[0].startswith('e,'): parts = coordinates.pop(0)[2:].split(',') end_point = QPointF(float(parts[0]), -float(parts[1])) # extract optional start_point if coordinates[0].startswith('s,'): parts = coordinates.pop(0).split(',') # first point parts = coordinates.pop(0).split(',') point = QPointF(float(parts[0]), -float(parts[1])) path = QPainterPath(point) while len(coordinates) > 2: # extract triple of points for a cubic spline parts = coordinates.pop(0).split(',') point1 = QPointF(float(parts[0]), -float(parts[1])) parts = coordinates.pop(0).split(',') point2 = QPointF(float(parts[0]), -float(parts[1])) parts = coordinates.pop(0).split(',') point3 = QPointF(float(parts[0]), -float(parts[1])) path.cubicTo(point1, point2, point3) self._arrow = None if end_point is not None: # draw arrow self._arrow = QGraphicsPolygonItem() polygon = QPolygonF() polygon.append(point3) offset = QPointF(end_point - point3) corner1 = QPointF(-offset.y(), offset.x()) * 0.35 corner2 = QPointF(offset.y(), -offset.x()) * 0.35 polygon.append(point3 + corner1) polygon.append(end_point) polygon.append(point3 + corner2) self._arrow.setPolygon(polygon) self._path = QGraphicsPathItem() self._path.setPath(path) self.addToGroup(self._path) self._brush.setColor(self._color) self._edge_pen.setColor(self._color) self._label_pen.setColor(self._color) self._path.setPen(self._edge_pen) if self._arrow is not None: self._arrow.setBrush(self._brush) self._arrow.setPen(self._edge_pen) if self._label is not None: self._label.setBrush(self._brush) self._label.setPen(self._label_pen)