def _generate_indicators(self, **kwargs): # pylint: disable=unused-argument """ Paint arrow indicators of selected instructions and labels. """ scene = self.scene() for item in self._map_indicator_items: scene.removeItem(item) self._map_indicator_items.clear() for addr in list(self.disasm_view.infodock.selected_insns) + list( self.disasm_view.infodock.selected_labels): pos = self._get_pos_from_addr(addr) if pos is None: continue pos -= 1 # this is the top-left x coordinate of our arrow body (the rectangle) pen = QPen(Qt.yellow) brush = QBrush(Qt.yellow) item = QGraphicsRectItem(QRectF(pos, 0, 2, 10), parent=self) item.setPen(pen) item.setBrush(brush) item.setZValue(self.ZVALUE_INDICATOR) self._map_indicator_items.append(item) triangle = QPolygonF() triangle.append(QPointF(pos - 1, 10)) triangle.append(QPointF(pos + 3, 10)) triangle.append(QPointF(pos + 1, 12)) triangle.append(QPointF(pos - 1, 10)) item = QGraphicsPolygonItem(triangle, parent=self) item.setPen(pen) item.setBrush(brush) item.setZValue(self.ZVALUE_INDICATOR) self._map_indicator_items.append(item)
class GameWindow(QGraphicsView): def __init__(self, parent=None): super(GameWindow, self).__init__(parent=parent) self.screen = None self.scene = QGraphicsScene() self.scene.setSceneRect( QRect(left=0, top=0, width=PLAYGROUND_SIZEX * SCALE_FACTORX, height=PLAYGROUND_SIZEY * SCALE_FACTORY)) self.setFrameStyle(4) self.setScene(self.scene) self.snake = [] # define SnakeHead self.snake.append(QGraphicsRectItem()) self.snake[0].setRect(QRect(0, 0, SCALE_FACTORX, SCALE_FACTORY)) self.snake[0].setBrush(brushHead) self.scene.addItem(self.snake[0]) # define rest of the snake for i in range(1, MAX_LENGTH_SNAKE): self.snake.append(QGraphicsRectItem()) self.snake[i].setRect(QRect(0, 0, SCALE_FACTORX, SCALE_FACTORY)) self.snake[i].setBrush(brushBody) self.snake[i].setVisible(False) self.scene.addItem(self.snake[i]) # Create the graphic item for apple self.goal = QGraphicsRectItem() self.goal.setRect(QRect(0, 0, SCALE_FACTORX, SCALE_FACTORY)) self.goal.setBrush(brushGoal) self.scene.addItem(self.goal) self.show() def draw(self, state): self.goal.setPos(state.goal.x * SCALE_FACTORX, state.goal.y * SCALE_FACTORY) self.goal.setVisible(True) self.snake[0].setPos(float(state.snake[0].x * SCALE_FACTORX), float(state.snake[0].y * SCALE_FACTORY)) for i in range(1, state.snake_length): self.snake[i].setPos(state.snake[i].x * SCALE_FACTORX, state.snake[i].y * SCALE_FACTORY) self.snake[i].setVisible(True) for i in range(state.snake_length, MAX_LENGTH_SNAKE): self.snake[i].setVisible(False) def screenshot(self): self.screen = self.grab() self.screen.save("./snake_screen.png")
def draw_bounding_box(self): df = self.page_df scale = self.zoom no_df = df[df.word=="redroverr2"] tle_df = df[df.word.str.contains("suf", na = False)] catt_df = df[df.word.str.contains("insuf", na=False)] rinder_df = df[df.word.str.contains("ind1111er", na=False)] for index, row in no_df.iterrows(): print(row) x1 = row.x1*scale y1 = row.y1*scale x3= row.x3*scale y3 = row.y3*scale diff_x = x3-x1 diff_y = y3-y1 rectItem = QGraphicsRectItem(x1,y1,diff_x,diff_y) rectItem.setBrush(QBrush(Qt.green)) #rectItem = QGraphicsRectItem(0, 0, 100, 100) self.scene.addItem(rectItem) for index, row in tle_df.iterrows(): print(row) x1 = row.x1 * scale y1 = row.y1 * scale x3 = row.x3 * scale y3 = row.y3 * scale diff_x = x3 - x1 diff_y = y3 - y1 rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y) rectItem.setBrush(QBrush(Qt.green)) # rectItem = QGraphicsRectItem(0, 0, 100, 100) self.scene.addItem(rectItem) for index, row in rinder_df.iterrows(): print(row) x1 = row.x1 * scale y1 = row.y1 * scale x3 = row.x3 * scale y3 = row.y3 * scale diff_x = x3 - x1 diff_y = y3 - y1 rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y) rectItem.setBrush(QBrush(Qt.red)) # rectItem = QGraphicsRectItem(0, 0, 100, 100) self.scene.addItem(rectItem) for index, row in catt_df.iterrows(): print(row) x1 = row.x1 * scale y1 = row.y1 * scale x3 = row.x3 * scale y3 = row.y3 * scale diff_x = x3 - x1 diff_y = y3 - y1 rectItem = QGraphicsRectItem(x1, y1, diff_x, diff_y) rectItem.setBrush(QBrush(Qt.red)) # rectItem = QGraphicsRectItem(0, 0, 100, 100) self.scene.addItem(rectItem)
def createItem(x, scene): rectItem = QGraphicsRectItem(QRectF(x + 40, 40, 120, 120)) scene.addItem(rectItem) rectItem.setPen(QPen(Qt.black)) rectItem.setBrush(Qt.gray) innerRectItem = QGraphicsRectItem(QRectF(x + 50, 50, 45, 100), rectItem) innerRectItem.setPen(QPen(Qt.black)) innerRectItem.setBrush(Qt.white) # scene.addItem(innerRectItem) ellipseItem = QGraphicsEllipseItem(QRectF(x + 105, 50, 45, 100), rectItem) ellipseItem.setPen(QPen(Qt.black)) ellipseItem.setBrush(Qt.white) # scene.addItem(ellipseItem) return rectItem
class NotificationListItem(QGraphicsTextItem): def __init__(self): """Notification list graphics item. Used to show notifications for a ProjectItem """ super().__init__() self.bg = QGraphicsRectItem(self.boundingRect(), self) bg_brush = QApplication.palette().brush(QPalette.ToolTipBase) self.bg.setBrush(bg_brush) self.bg.setFlag(QGraphicsItem.ItemStacksBehindParent) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=False) self.setZValue(2) def setHtml(self, html): super().setHtml(html) self.adjustSize() self.bg.setRect(self.boundingRect())
class ObjectLabelItem(QGraphicsTextItem): """Provides a label for ObjectItem's.""" entity_name_edited = Signal(str) def __init__(self, entity_item): """Initializes item. Args: entity_item (spinetoolbox.widgets.graph_view_graphics_items.EntityItem): The parent item. """ super().__init__(entity_item) self.entity_item = entity_item self._font = QApplication.font() self._font.setPointSize(11) self.setFont(self._font) self.bg = QGraphicsRectItem(self) self.bg_color = QGuiApplication.palette().color( QPalette.Normal, QPalette.ToolTipBase) self.bg_color.setAlphaF(0.8) self.bg.setBrush(QBrush(self.bg_color)) self.bg.setPen(Qt.NoPen) self.bg.setFlag(QGraphicsItem.ItemStacksBehindParent) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=False) self.setAcceptHoverEvents(False) self._cursor = self.textCursor() self._text_backup = None def setPlainText(self, text): """Set texts and resets position. Args: text (str) """ super().setPlainText(text) self.reset_position() def reset_position(self): """Adapts item geometry so text is always centered.""" rectf = self.boundingRect() x = -rectf.width() / 2 y = rectf.height() + 4 self.setPos(x, y) self.bg.setRect(self.boundingRect())
def __init__(self, parent: QWidget = None) -> None: """ Create a GraphicsView for Facile. :param parent: The widget to embed the graphics view into :type parent: QWidget :return: None :rtype: NoneType """ super(FacileGraphicsView, self).__init__(parent) # set flags self.setDragMode(QGraphicsView.ScrollHandDrag) self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) # show initial message scene = QGraphicsScene() box = QGraphicsRectItem(0, 0, 100, 100) box.setPen(QColor(Qt.transparent)) box.setBrush(QColor(Qt.transparent)) QGraphicsTextItem("Nothing to show here yet!", box) scene.addItem(box) self.setScene(scene)
class RankIcon(QGraphicsTextItem): def __init__(self, parent): """Rank icon graphics item. Used to show the rank of a ProjectItem within its DAG Args: parent (ProjectItemIcon): the parent item """ super().__init__(parent) self._parent = parent rect_w = parent.rect().width() # Parent rect width self.text_margin = 0.05 * rect_w self.bg = QGraphicsRectItem(self.boundingRect(), self) bg_brush = QApplication.palette().brush(QPalette.ToolTipBase) self.bg.setBrush(bg_brush) self.bg.setFlag(QGraphicsItem.ItemStacksBehindParent) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=False) font = self.font() font.setPointSize(parent.text_font_size) font.setBold(True) self.setFont(font) doc = self.document() doc.setDocumentMargin(0) def set_rank(self, rank): self.setPlainText(str(rank)) self.adjustSize() self.setTextWidth(self.text_margin + self.textWidth()) self.bg.setRect(self.boundingRect()) # Align center fmt = QTextBlockFormat() fmt.setAlignment(Qt.AlignHCenter) cursor = self.textCursor() cursor.select(QTextCursor.Document) cursor.mergeBlockFormat(fmt) cursor.clearSelection() self.setTextCursor(cursor)
class MaskScene(QGraphicsScene): _stage_text = 'STAGE %s' def __init__(self, main_window, stage=1): super().__init__() self.main_window = main_window self.stage = stage self.upper_mask = QGraphicsRectItem(0, 0, content_width, 0) self.lower_mask = QGraphicsRectItem(0, content_height, content_width, 0) self.stage_text_item = QGraphicsTextItem() self.mask_height = 0 self.animation_timer_1 = QTimer() self.animation_timer_2 = QTimer() self.animation_timer_3 = QTimer() self.selected = None self.init() def init(self): mask_brush = QBrush() mask_brush.setColor(Qt.gray) mask_brush.setStyle(Qt.SolidPattern) mask_pen = QPen() mask_pen.setColor(Qt.gray) self.upper_mask.setBrush(mask_brush) self.lower_mask.setBrush(mask_brush) self.upper_mask.setPen(mask_pen) self.lower_mask.setPen(mask_pen) self.addItem(self.upper_mask) self.addItem(self.lower_mask) font = QFont() font.setPointSize(20) font.setBold(True) self.stage_text_item.setPlainText(self._stage_text % self.stage) self.stage_text_item.setFont(font) self.stage_text_item.setDefaultTextColor(Qt.black) self.stage_text_item.setX(content_width / 2 - int(self.stage_text_item.boundingRect().width() / 2)) self.stage_text_item.setY(content_height / 2 - int(self.stage_text_item.boundingRect().height() / 2)) self.animation_timer_1.setInterval(interval) self.animation_timer_1.timeout.connect(self.animation_in) self.animation_timer_2.setSingleShot(True) self.animation_timer_2.timeout.connect(self.animation_hold) self.animation_timer_2.setInterval(800) self.animation_timer_3.setInterval(interval) self.animation_timer_3.timeout.connect(self.animation_out) def next_stage(self): self.stage += 1 self.stage_text_item.setPlainText(self._stage_text % self.stage) def reset_stage(self): self.stage = 0 self.stage_text_item.setPlainText(self._stage_text % self.stage) def animation_in(self): self.mask_height += 10 finished = False if self.mask_height > content_height / 2: self.mask_height = content_height / 2 finished = True self.upper_mask.setRect(0, 0, content_width, self.mask_height) self.lower_mask.setRect(0, content_height - self.mask_height, content_width, self.mask_height) if finished: self.addItem(self.stage_text_item) self.animation_timer_1.stop() self.animation_timer_2.start() def animation_out(self): self.mask_height -= 10 finished = False if self.mask_height < 0: self.mask_height = 0 finished = True self.upper_mask.setRect(0, 0, content_width, self.mask_height) self.lower_mask.setRect(0, content_height - self.mask_height, content_width, self.mask_height) if finished: self.animation_timer_3.stop() self.main_window.start_game(self.selected) def animation_hold(self): self.removeItem(self.stage_text_item) self.animation_timer_3.start() self.main_window.enter_game_scene() def start_animation(self, selected: int): self.animation_timer_1.start() self.selected = selected
class EntityItem(QGraphicsRectItem): """Base class for ObjectItem and RelationshipItem.""" def __init__(self, spine_db_editor, x, y, extent, db_map_entity_id=None): """Initializes item Args: spine_db_editor (SpineDBEditor): 'owner' x (float): x-coordinate of central point y (float): y-coordinate of central point extent (int): Preferred extent db_map_entity_id (tuple): db_map, entity id """ super().__init__() self._spine_db_editor = spine_db_editor self.db_mngr = spine_db_editor.db_mngr self.db_map_entity_id = db_map_entity_id self.arc_items = list() self._extent = extent self.setRect(-0.5 * self._extent, -0.5 * self._extent, self._extent, self._extent) self.setPen(Qt.NoPen) self._svg_item = QGraphicsSvgItem(self) self._svg_item.setCacheMode( QGraphicsItem.CacheMode.NoCache ) # Needed for the exported pdf to be vector self.refresh_icon() self.setPos(x, y) self._moved_on_scene = False self._bg = None self._bg_brush = Qt.NoBrush self._init_bg() self._bg.setFlag(QGraphicsItem.ItemStacksBehindParent, enabled=True) self.setZValue(0) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=True) self.setFlag(QGraphicsItem.ItemIsMovable, enabled=True) self.setFlag(QGraphicsItem.ItemIgnoresTransformations, enabled=True) self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges, enabled=True) self.setAcceptHoverEvents(True) self.setCursor(Qt.ArrowCursor) self.setToolTip(self._make_tool_tip()) def _make_tool_tip(self): raise NotImplementedError() @property def entity_type(self): raise NotImplementedError() @property def entity_name(self): return self.db_mngr.get_item(self.db_map, self.entity_type, self.entity_id)["name"] @property def entity_class_type(self): return { "relationship": "relationship_class", "object": "object_class" }[self.entity_type] @property def entity_class_id(self): return self.db_mngr.get_item(self.db_map, self.entity_type, self.entity_id)["class_id"] @property def entity_class_name(self): return self.db_mngr.get_item(self.db_map, self.entity_class_type, self.entity_class_id)["name"] @property def db_map(self): return self.db_map_entity_id[0] @property def entity_id(self): return self.db_map_entity_id[1] @property def first_db_map(self): return self.db_map @property def display_data(self): return self.entity_name @property def display_database(self): return self.db_map.codename @property def db_maps(self): return (self.db_map, ) def db_map_data(self, _db_map): # NOTE: Needed by EditObjectsDialog and EditRelationshipsDialog return self.db_mngr.get_item(self.db_map, self.entity_type, self.entity_id) def db_map_id(self, _db_map): # NOTE: Needed by EditObjectsDialog and EditRelationshipsDialog return self.entity_id def boundingRect(self): return super().boundingRect() | self.childrenBoundingRect() def moveBy(self, dx, dy): super().moveBy(dx, dy) self.update_arcs_line() def _init_bg(self): self._bg = QGraphicsRectItem(self.boundingRect(), self) self._bg.setPen(Qt.NoPen) def refresh_icon(self): """Refreshes the icon.""" renderer = self.db_mngr.entity_class_renderer(self.db_map, self.entity_class_type, self.entity_class_id) self._set_renderer(renderer) def _set_renderer(self, renderer): self._svg_item.setSharedRenderer(renderer) size = renderer.defaultSize() scale = self._extent / max(size.width(), size.height()) self._svg_item.setScale(scale) self._svg_item.setPos(self.rect().center() - 0.5 * scale * QPointF(size.width(), size.height())) def shape(self): """Returns a shape containing the entire bounding rect, to work better with icon transparency.""" path = QPainterPath() path.setFillRule(Qt.WindingFill) path.addRect(self._bg.boundingRect()) return path def paint(self, painter, option, widget=None): """Shows or hides the selection halo.""" if option.state & (QStyle.State_Selected): self._paint_as_selected() option.state &= ~QStyle.State_Selected else: self._paint_as_deselected() super().paint(painter, option, widget) def _paint_as_selected(self): self._bg.setBrush(QGuiApplication.palette().highlight()) def _paint_as_deselected(self): self._bg.setBrush(self._bg_brush) def add_arc_item(self, arc_item): """Adds an item to the list of arcs. Args: arc_item (ArcItem) """ self.arc_items.append(arc_item) arc_item.update_line() def apply_zoom(self, factor): """Applies zoom. Args: factor (float): The zoom factor. """ if factor > 1: factor = 1 self.setScale(factor) def apply_rotation(self, angle, center): """Applies rotation. Args: angle (float): The angle in degrees. center (QPoint): Rotates around this point. """ line = QLineF(center, self.pos()) line.setAngle(line.angle() + angle) self.setPos(line.p2()) self.update_arcs_line() def block_move_by(self, dx, dy): self.moveBy(dx, dy) def mouseMoveEvent(self, event): """Moves the item and all connected arcs. Args: event (QGraphicsSceneMouseEvent) """ if event.buttons() & Qt.LeftButton == 0: super().mouseMoveEvent(event) return move_by = event.scenePos() - event.lastScenePos() # Move selected items together for item in self.scene().selectedItems(): if isinstance(item, (EntityItem)): item.block_move_by(move_by.x(), move_by.y()) def update_arcs_line(self): """Moves arc items.""" for item in self.arc_items: item.update_line() def itemChange(self, change, value): """ Keeps track of item's movements on the scene. Args: change (GraphicsItemChange): a flag signalling the type of the change value: a value related to the change Returns: the same value given as input """ if change == QGraphicsItem.ItemScenePositionHasChanged: self._moved_on_scene = True return value def set_all_visible(self, on): """Sets visibility status for this item and all arc items. Args: on (bool) """ for item in self.arc_items: item.setVisible(on) self.setVisible(on) def _make_menu(self): return self._spine_db_editor.ui.graphicsView.make_items_menu() def contextMenuEvent(self, e): """Shows context menu. Args: e (QGraphicsSceneMouseEvent): Mouse event """ e.accept() if not self.isSelected() and not e.modifiers() & Qt.ControlModifier: self.scene().clearSelection() self.setSelected(True) menu = self._make_menu() menu.popup(e.screenPos())
class EntityItem(QGraphicsPixmapItem): """Base class for ObjectItem and RelationshipItem.""" def __init__(self, data_store_form, x, y, extent, entity_id=None): """Initializes item Args: data_store_form (DataStoreForm): 'owner' x (float): x-coordinate of central point y (float): y-coordinate of central point extent (int): Preferred extent entity_id (int): The entity id """ super().__init__() self._data_store_form = data_store_form self.db_mngr = data_store_form.db_mngr self.db_map = data_store_form.db_map self.entity_id = entity_id self.arc_items = list() self._extent = extent self.refresh_icon() self.setPos(x, y) rect = self.boundingRect() self.setOffset(-rect.width() / 2, -rect.height() / 2) self._moved_on_scene = False self._bg = None self._bg_brush = Qt.NoBrush self._init_bg() self._bg.setFlag(QGraphicsItem.ItemStacksBehindParent, enabled=True) self.setZValue(0) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=True) self.setFlag(QGraphicsItem.ItemIsMovable, enabled=True) self.setFlag(QGraphicsItem.ItemIgnoresTransformations, enabled=True) self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges, enabled=True) self.setAcceptHoverEvents(True) self.setCursor(Qt.ArrowCursor) @property def entity_type(self): raise NotImplementedError() @property def entity_name(self): return self.db_mngr.get_item(self.db_map, self.entity_type, self.entity_id)["name"] @property def entity_class_type(self): return { "relationship": "relationship class", "object": "object class" }[self.entity_type] @property def entity_class_id(self): return self.db_mngr.get_item(self.db_map, self.entity_type, self.entity_id)["class_id"] @property def entity_class_name(self): return self.db_mngr.get_item(self.db_map, self.entity_class_type, self.entity_class_id)["name"] @property def first_db_map(self): return self.db_map @property def display_data(self): return self.entity_name @property def display_database(self): return self.db_map.codename @property def db_maps(self): return (self.db_map, ) def db_map_data(self, _db_map): return self.db_mngr.get_item(self.db_map, self.entity_type, self.entity_id) def db_map_id(self, _db_map): return self.entity_id def boundingRect(self): return super().boundingRect() | self.childrenBoundingRect() def moveBy(self, dx, dy): super().moveBy(dx, dy) self.update_arcs_line() def _init_bg(self): self._bg = QGraphicsRectItem(self.boundingRect(), self) self._bg.setPen(Qt.NoPen) def refresh_icon(self): """Refreshes the icon.""" pixmap = self.db_mngr.entity_class_icon( self.db_map, self.entity_class_type, self.entity_class_id).pixmap(self._extent) self.setPixmap(pixmap) def shape(self): """Returns a shape containing the entire bounding rect, to work better with icon transparency.""" path = QPainterPath() path.setFillRule(Qt.WindingFill) path.addRect(self._bg.boundingRect()) return path def paint(self, painter, option, widget=None): """Shows or hides the selection halo.""" if option.state & (QStyle.State_Selected): self._paint_as_selected() option.state &= ~QStyle.State_Selected else: self._paint_as_deselected() super().paint(painter, option, widget) def _paint_as_selected(self): self._bg.setBrush(QGuiApplication.palette().highlight()) def _paint_as_deselected(self): self._bg.setBrush(self._bg_brush) def add_arc_item(self, arc_item): """Adds an item to the list of arcs. Args: arc_item (ArcItem) """ self.arc_items.append(arc_item) arc_item.update_line() def apply_zoom(self, factor): """Applies zoom. Args: factor (float): The zoom factor. """ if factor > 1: factor = 1 self.setScale(factor) def apply_rotation(self, angle, center): """Applies rotation. Args: angle (float): The angle in degrees. center (QPoint): Rotates around this point. """ line = QLineF(center, self.pos()) line.setAngle(line.angle() + angle) self.setPos(line.p2()) self.update_arcs_line() def block_move_by(self, dx, dy): self.moveBy(dx, dy) def mouseMoveEvent(self, event): """Moves the item and all connected arcs. Also checks for a merge target and sets an appropriate mouse cursor. Args: event (QGraphicsSceneMouseEvent) """ if event.buttons() & Qt.LeftButton == 0: super().mouseMoveEvent(event) return move_by = event.scenePos() - event.lastScenePos() # Move selected items together for item in self.scene().selectedItems(): if isinstance(item, (EntityItem)): item.block_move_by(move_by.x(), move_by.y()) def update_arcs_line(self): """Moves arc items.""" for item in self.arc_items: item.update_line() def itemChange(self, change, value): """ Keeps track of item's movements on the scene. Args: change (GraphicsItemChange): a flag signalling the type of the change value: a value related to the change Returns: the same value given as input """ if change == QGraphicsItem.ItemScenePositionHasChanged: self._moved_on_scene = True return value def set_all_visible(self, on): """Sets visibility status for this item and all arc items. Args: on (bool) """ for item in self.arc_items: item.setVisible(on) self.setVisible(on) def _make_menu(self): menu = QMenu(self._data_store_form) menu.addAction(self._data_store_form.ui.actionSave_positions) menu.addAction(self._data_store_form.ui.actionClear_positions) menu.addSeparator() menu.addAction(self._data_store_form.ui.actionHide_selected) menu.addAction(self._data_store_form.ui.actionPrune_selected_entities) menu.addAction(self._data_store_form.ui.actionPrune_selected_classes) menu.addSeparator() menu.addAction(self._data_store_form.ui.actionEdit_selected) menu.addAction(self._data_store_form.ui.actionRemove_selected) return menu def contextMenuEvent(self, e): """Shows context menu. Args: e (QGraphicsSceneMouseEvent): Mouse event """ e.accept() if not self.isSelected() and not e.modifiers() & Qt.ControlModifier: self.scene().clearSelection() self.setSelected(True) self._data_store_form._handle_menu_graph_about_to_show() self._menu.popup(e.screenPos())
class TextLineItem(QAbstractGraphicsShapeItem): """A one-line text item. Default origin point is at the left side of the baseline. This can change if setAlignMode is called. TextLineItem also supports drawing text background. Its brush can be set using setBackgroundBrush(). Text must not contain newline characters. """ def __init__(self, text=None, parent=None): super().__init__(parent) self._text = text or "" self._elided_text = text or "" self._elide_mode = Qt.ElideRight self._align_mode = Qt.AlignLeft self._max_width = None self._font = QFont() self._bounding_rect = QRectF() """Bounding and drawing rectangle. Determined automatically.""" self.background = QGraphicsRectItem(self) self.background.setPen(Qt.NoPen) self.background.setFlag(QGraphicsItem.ItemStacksBehindParent) self.adjust() def setText(self, text: str, /) -> None: if '\n' in text: raise ValueError("text must not contain newline characters") self.prepareGeometryChange() self._text = text self.adjust() def setElideMode(self, mode: int, /) -> None: """Elide mode specifies where the ellipsis should be located when the text is elided. Default value is Qt.ElideRight. """ self.prepareGeometryChange() self._elide_mode = mode self.adjust() def setAlignMode(self, mode: int, /) -> None: """Align mode specifies text alignment. Text alignment changes the origin point x position: - If mode is Qt.AlignLeft, the origin point is on the left of the baseline. - If mode is Qt.AlignHCenter, the origin point is in the center of the baseline. - If mode is Qt.AlignRight, the origin point is on the right of the baseline. Vertical alignment has no meaning for one line of text and should not be set. Default value is Qt.AlignLeft. """ self.prepareGeometryChange() self._align_mode = mode self.adjust() def setMaximumWidth(self, width, /): """Set the maximum width the text is allowed to be. `None` represents unlimited width.""" self.prepareGeometryChange() self._max_width = width self.adjust() def setFont(self, font: QFont, /) -> None: self.prepareGeometryChange() self._font = font self.adjust() def setBackgroundBrush(self, brush: QBrush, /): self.background.setBrush(brush) def text(self) -> str: return self._text def elidedText(self) -> str: return self._elided_text def elideMode(self) -> int: return self._elide_mode def alignMode(self) -> int: return self._align_mode def maximumWidth(self): """Maximum width the text is allowed to be. `None` represents unlimited width.""" return self._max_width def font(self) -> QFont: return self._font def backgroundBrush(self): return self.background.brush() def adjust(self): """Adjust the item's geometry in response to changes.""" metrics = QFontMetricsF(self.font()) # Get bounding rectangle for full text self._bounding_rect = metrics.boundingRect(self.text()) # Constrain by maximum width if self.maximumWidth() is not None: self._bounding_rect.setWidth(self.maximumWidth()) # Compute elided text self._elided_text = metrics.elidedText(self.text(), self.elideMode(), self.boundingRect().width()) # Get bounding rectangle for elided text self._bounding_rect = metrics.boundingRect(self.elidedText()) # It seems that for small characters like "..." the bounding rect returned is too small. Adjust it by a small # value. metrics_correction = px(1 / 72) self._bounding_rect.adjust(-metrics_correction, 0, metrics_correction, 0) # Move origin point according to the alignment if self.alignMode() & Qt.AlignLeft: self._bounding_rect.moveLeft(0) elif self.alignMode() & Qt.AlignRight: self._bounding_rect.moveRight(0) else: self._bounding_rect.moveLeft(-self._bounding_rect.width() / 2) # Set background rect self.background.setRect(self.boundingRect()) def boundingRect(self) -> QRectF: return self._bounding_rect def paint(self, painter: QPainter, option, widget=...) -> None: painter.setBrush(self.brush()) painter.setPen(self.pen()) painter.setFont(self.font()) painter.drawText(self.boundingRect(), self.alignMode(), self.elidedText())
class EntityLabelItem(QGraphicsTextItem): """Label item for items in GraphViewForm.""" entity_name_edited = Signal(str) def __init__(self, entity_item): """Initializes item. Args: entity_item (spinetoolbox.widgets.graph_view_graphics_items.EntityItem): The parent item. """ super().__init__(entity_item) self.entity_item = entity_item self._font = QApplication.font() self._font.setPointSize(11) self.setFont(self._font) self.bg = QGraphicsRectItem(self) color = QGuiApplication.palette().color(QPalette.Normal, QPalette.ToolTipBase) color.setAlphaF(0.8) self.set_bg_color(color) self.bg.setFlag(QGraphicsItem.ItemStacksBehindParent) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=False) self.setAcceptHoverEvents(False) self._cursor = self.textCursor() self._text_backup = None def setPlainText(self, text): """Set texts and resets position. Args: text (str) """ super().setPlainText(text) self.reset_position() def reset_position(self): """Adapts item geometry so text is always centered.""" rectf = self.boundingRect() x = -rectf.width() / 2 y = rectf.height() + 4 self.setPos(x, y) self.bg.setRect(self.boundingRect()) def set_bg_color(self, bg_color): """Sets background color. Args: bg_color (QColor) """ self.bg.setBrush(QBrush(bg_color)) def start_editing(self): """Starts editing.""" self.setTextInteractionFlags(Qt.TextEditorInteraction) self.setFocus() cursor = QTextCursor(self._cursor) cursor.select(QTextCursor.Document) self.setTextCursor(cursor) self._text_backup = self.toPlainText() def keyPressEvent(self, event): """Keeps text centered as the user types. Gives up focus when the user presses Enter or Return. Args: event (QKeyEvent) """ if event.key() in (Qt.Key_Return, Qt.Key_Enter): self.clearFocus() elif event.key() == Qt.Key_Escape: self.setPlainText(self._text_backup) self.clearFocus() else: super().keyPressEvent(event) self.reset_position() def focusOutEvent(self, event): """Ends editing and sends entity_name_edited signal.""" super().focusOutEvent(event) self.setTextInteractionFlags(Qt.NoTextInteraction) self.entity_name_edited.emit(self.toPlainText()) self.setTextCursor(self._cursor) def mouseDoubleClickEvent(self, event): """Starts editing the name. Args: event (QGraphicsSceneMouseEvent) """ self.start_editing()
def drawTile(self, i, j): rect = QGraphicsRectItem(j * self.nPieceWidth, i * self.nPieceWidth, self.nPieceWidth, self.nPieceWidth) if i % 2 == j % 2: if self.selectCell[i][ j]: # Selected cells only get the selection background color rect.setBrush(QBrush(self.cLightSquareColorSelected)) elif self.focusCell[i][j]: if self.threatCell[i][j]: rect.setBrush(QBrush(self.cLightSquareColorFocusDanger)) else: rect.setBrush(QBrush(self.cLightSquareColorFocus)) else: # If the cell has no focus, it also has no danger indication rect.setBrush(QBrush(self.cLightSquareColor)) else: if self.selectCell[i][ j]: # Selectd cells only get the selection background color rect.setBrush(QBrush(self.cDarkSquareColorSelected)) elif self.focusCell[i][j]: if self.threatCell[i][j]: rect.setBrush(QBrush(self.cDarkSquareColorFocusDanger)) else: rect.setBrush(QBrush(self.cDarkSquareColorFocus)) else: # If the cell has no focus, it also has no danger indication rect.setBrush(QBrush(self.cDarkSquareColor)) rect.setCacheMode(QGraphicsItem.NoCache) self.addItem(rect)
class MonitorItem(QGraphicsRectItem, QObject): z = 0 def __init__(self, *a, **kw): data = kw.pop("data") self.name = kw.pop("name") self.window = kw.pop("window") super().__init__(0, 0, 0, 0) self.setAcceptedMouseButtons(Qt.LeftButton) self.label = QGraphicsTextItem("", self) self.bottom_edge = QGraphicsRectItem(0, 0, 0, 0, self) self.bottom_edge.setBrush(QBrush("red", Qt.SolidPattern)) self.update_visuals(data) def update_visuals(self, data): self.setRect(0, 0, data["res_x"], data["res_y"]) self.setPos(data["pos_x"], data["pos_y"]) if data["orientation"] == 0: self.bottom_edge.setRect(0, data["res_y"] - 50, data["res_x"], 50) elif data["orientation"] == 1: self.bottom_edge.setRect(data["res_x"] - 50, 0, 50, data["res_y"]) elif data["orientation"] == 2: self.bottom_edge.setRect(0, 0, data["res_x"], 50) elif data["orientation"] == 3: self.bottom_edge.setRect(0, 0, 50, data["res_y"]) if data["replica_of"]: label_text = f"{self.name} [{','.join(data['replica_of'])}]" else: label_text = self.name self.label.setPlainText(label_text) label_scale = min( self.rect().width() / self.label.boundingRect().width(), self.rect().height() / self.label.boundingRect().height(), ) self.label.setScale(label_scale) if data["enabled"]: if data["primary"]: color = QColor("#eee8d5") color.setAlpha(200) self.setBrush(QBrush(color, Qt.SolidPattern)) self.setZValue(1000) else: color = QColor("#ffffff") color.setAlpha(200) self.setBrush(QBrush(color, Qt.SolidPattern)) self.setZValue(self.z) self.z -= 1 else: color = QColor("#f1f1f1") color.setAlpha(200) self.setBrush(QBrush(color, Qt.SolidPattern)) self.setZValue(-1000) if not data["current_mode"]: # Disconnected or disabled self.hide() else: self.show() def mousePressEvent(self, event): self.window.pos_label.show() self.setCursor(Qt.ClosedHandCursor) self.orig_pos = self.pos() self.window.ui.screenCombo.setCurrentText(self.name) def mouseReleaseEvent(self, event): self.setCursor(Qt.OpenHandCursor) self.window.monitor_moved() self.window.pos_label.hide() def mouseMoveEvent(self, event): view = event.widget().parent() click_pos = event.buttonDownScreenPos(Qt.LeftButton) current_pos = event.screenPos() self.setPos( view.mapToScene( view.mapFromScene(self.orig_pos) + current_pos - click_pos)) self.window.show_pos(int(self.pos().x()), int(self.pos().y()))
def _create_line_indicator(self, addr, item_map, color=Qt.yellow, show_frontier=False, z=None, z_frontier=None): """ Generate a cursor at a given address. """ pos_x = self._get_pos_from_addr(addr) if pos_x is None: return pen = QPen(color) brush = QBrush(color) height = self.height tri_width = 7 tri_height = 4 pos_x = int(pos_x - tri_width / 2) # Center drawing center = pos_x + int(tri_width / 2) pos_y = 0 frontier_width = int(0.15 * max(self.width, self.height)) if show_frontier: # Draw frontier gradients r = QRectF(center - frontier_width, pos_y, frontier_width, height) bg = QLinearGradient(r.topLeft(), r.topRight()) color = Qt.red top_color = QColor(color) top_color.setAlpha(0) bg.setColorAt(0, top_color) bottom_color = QColor(color) bottom_color.setAlpha(180) bg.setColorAt(1, bottom_color) i = QGraphicsRectItem(r, parent=self) i.setPen(Qt.NoPen) i.setBrush(bg) if z_frontier is not None: i.setZValue(z_frontier) item_map.append(i) r = QRectF(center, pos_y, frontier_width, height) bg = QLinearGradient(r.topLeft(), r.topRight()) color = Qt.blue top_color = QColor(color) bg.setColorAt(0, top_color) bottom_color = QColor(color) bottom_color.setAlpha(0) bg.setColorAt(1, bottom_color) i = QGraphicsRectItem(r, parent=self) i.setPen(Qt.NoPen) i.setBrush(bg) if z_frontier is not None: i.setZValue(z_frontier) item_map.append(i) # Draw line i = QGraphicsLineItem(center, 0, center, height, parent=self) i.setPen(pen) if z is not None: i.setZValue(z) item_map.append(i) # Draw top and bottom triangles t = QPolygonF() t.append(QPointF(pos_x, pos_y)) t.append(QPointF(pos_x + tri_width - 1, pos_y)) t.append(QPointF(center, pos_y + tri_height - 1)) t.append(QPointF(pos_x, pos_y)) pos_y += height - 1 b = QPolygonF() b.append(QPointF(pos_x, pos_y)) b.append(QPointF(center, pos_y - tri_height + 1)) b.append(QPointF(pos_x + tri_width - 1, pos_y)) b.append(QPointF(pos_x, pos_y)) for i in [QGraphicsPolygonItem(t, parent=self), QGraphicsPolygonItem(b, parent=self)]: i.setPen(pen) i.setBrush(brush) if z is not None: i.setZValue(z) item_map.append(i)
class EntityItem(QGraphicsPixmapItem): def __init__(self, graph_view_form, x, y, extent, entity_id=None, entity_class_id=None): """Initializes item Args: graph_view_form (GraphViewForm): 'owner' x (float): x-coordinate of central point y (float): y-coordinate of central point extent (int): Preferred extent entity_id (int, optional): The entity id in case of a non-wip item entity_class_id (int, optional): The entity class id in case of a wip item """ if not entity_id and not entity_class_id: raise ValueError( "Can't create an RelationshipItem without relationship id nor relationship class id." ) super().__init__() self._graph_view_form = graph_view_form self.db_mngr = graph_view_form.db_mngr self.db_map = graph_view_form.db_map self.entity_id = entity_id self._entity_class_id = entity_class_id self._entity_name = f"<WIP {self.entity_class_name}>" self.arc_items = list() self._extent = extent self.refresh_icon() self.setPos(x, y) rect = self.boundingRect() self.setOffset(-rect.width() / 2, -rect.height() / 2) self._press_pos = None self._merge_target = None self._moved_on_scene = False self._view_transform = QTransform( ) # To determine collisions in the view self._views_cursor = {} self._bg = None self._bg_brush = Qt.NoBrush self._init_bg() self._bg.setFlag(QGraphicsItem.ItemStacksBehindParent, enabled=True) self.is_wip = None self._question_item = None # In case this becomes a template if not self.entity_id: self.become_wip() else: self.become_whole() self.setZValue(0) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=True) self.setFlag(QGraphicsItem.ItemIsMovable, enabled=True) self.setFlag(QGraphicsItem.ItemIgnoresTransformations, enabled=True) self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges, enabled=True) self.setAcceptHoverEvents(True) self.setCursor(Qt.ArrowCursor) @property def entity_type(self): raise NotImplementedError() @property def entity_name(self): return self.db_mngr.get_item(self.db_map, self.entity_type, self.entity_id).get( "name", self._entity_name) @property def entity_class_type(self): return { "relationship": "relationship class", "object": "object class" }[self.entity_type] @property def entity_class_id(self): return self.db_mngr.get_item(self.db_map, self.entity_type, self.entity_id).get( "class_id", self._entity_class_id) @property def entity_class_name(self): return self.db_mngr.get_item(self.db_map, self.entity_class_type, self.entity_class_id)["name"] def boundingRect(self): return super().boundingRect() | self.childrenBoundingRect() def _init_bg(self): self._bg = QGraphicsRectItem(self.boundingRect(), self) self._bg.setPen(Qt.NoPen) def refresh_icon(self): """Refreshes the icon.""" pixmap = self.db_mngr.entity_class_icon( self.db_map, self.entity_class_type, self.entity_class_id).pixmap(self._extent) self.setPixmap(pixmap) def shape(self): """Returns a shape containing the entire bounding rect, to work better with icon transparency.""" path = QPainterPath() path.addRect(self.boundingRect()) return path def paint(self, painter, option, widget=None): """Shows or hides the selection halo.""" if option.state & (QStyle.State_Selected): self._paint_as_selected() option.state &= ~QStyle.State_Selected else: self._paint_as_deselected() super().paint(painter, option, widget) def _paint_as_selected(self): self._bg.setBrush(QGuiApplication.palette().highlight()) def _paint_as_deselected(self): self._bg.setBrush(self._bg_brush) def add_arc_item(self, arc_item): """Adds an item to the list of arcs. Args: arc_item (ArcItem) """ self.arc_items.append(arc_item) def become_wip(self): """Turns this item into a work-in-progress.""" self.is_wip = True font = QFont("", 0.6 * self._extent) self._question_item = OutlinedTextItem("?", self, font) # Position question item rect = super().boundingRect() question_rect = self._question_item.boundingRect() x = rect.center().x() - question_rect.width() / 2 y = rect.center().y() - question_rect.height() / 2 self._question_item.setPos(x, y) self.setToolTip(self._make_wip_tool_tip()) def _make_wip_tool_tip(self): raise NotImplementedError() def become_whole(self): """Removes the wip status from this item.""" self.is_wip = False if self._question_item: self.scene().removeItem(self._question_item) def adjust_to_zoom(self, transform): """Saves the view's transform to determine collisions later on. Args: transform (QTransform): The view's transformation matrix after the zoom. """ self._view_transform = transform factor = transform.m11() self.setFlag(QGraphicsItem.ItemIgnoresTransformations, enabled=factor > 1) def device_rect(self): """Returns the item's rect in devices's coordinates. Used to accurately determine collisions. """ return self.deviceTransform(self._view_transform).mapRect( super().boundingRect()) def _find_merge_target(self): """Returns a suitable merge target if any. Returns: spinetoolbox.widgets.graph_view_graphics_items.EntityItem, NoneType """ scene = self.scene() if not scene: return None colliding = [ x for x in scene.items() if isinstance(x, EntityItem) and x is not self and x.device_rect().intersects(self.device_rect()) ] return next(iter(colliding), None) # pylint: disable=no-self-use def _is_target_valid(self): """Whether or not the registered merge target is valid. Returns: bool """ return False # pylint: disable=no-self-use def merge_into_target(self, force=False): """Merges this item into the registered target if valid. Returns: bool: True if merged, False if not. """ return False def mousePressEvent(self, event): """Saves original position for bouncing purposes. Args: event (QGraphicsSceneMouseEvent) """ super().mousePressEvent(event) self._press_pos = self.pos() self._merge_target = None def mouseMoveEvent(self, event): """Moves the item and all connected arcs. Also checks for a merge target and sets an appropriate mouse cursor. Args: event (QGraphicsSceneMouseEvent) """ if event.buttons() & Qt.LeftButton == 0: super().mouseMoveEvent(event) return move_by = event.scenePos() - event.lastScenePos() # Move selected items together for item in self.scene().selectedItems(): if isinstance(item, (EntityItem)): item.moveBy(move_by.x(), move_by.y()) item.move_arc_items(move_by) self._merge_target = self._find_merge_target() for view in self.scene().views(): self._views_cursor.setdefault(view, view.viewport().cursor()) if not self._merge_target: try: view.viewport().setCursor(self._views_cursor[view]) except KeyError: pass continue if self._is_target_valid(): view.viewport().setCursor(Qt.DragCopyCursor) else: view.viewport().setCursor(Qt.ForbiddenCursor) def move_arc_items(self, pos_diff): """Moves arc items. Args: pos_diff (QPoint) """ raise NotImplementedError() def mouseReleaseEvent(self, event): """Merges the item into the registered target if any. Bounces it if not possible. Shrinks the scene if needed. Args: event (QGraphicsSceneMouseEvent) """ super().mouseReleaseEvent(event) if self._merge_target: if self.merge_into_target(): return self._bounce_back(self.pos()) if self._moved_on_scene: self._moved_on_scene = False scene = self.scene() scene.shrink_if_needed() scene.item_move_finished.emit(self) def _bounce_back(self, current_pos): """Bounces the item back from given position to its original position. Args: current_pos (QPoint) """ if self._press_pos is None: return self.move_arc_items(self._press_pos - current_pos) self.setPos(self._press_pos) def itemChange(self, change, value): """ Keeps track of item's movements on the scene. Args: change (GraphicsItemChange): a flag signalling the type of the change value: a value related to the change Returns: the same value given as input """ if change == QGraphicsItem.ItemScenePositionHasChanged: self._moved_on_scene = True return value def set_all_visible(self, on): """Sets visibility status for this item and all arc items. Args: on (bool) """ for item in self.arc_items: item.setVisible(on) self.setVisible(on) def wipe_out(self): """Removes this item and all its arc items from the scene.""" self.scene().removeItem(self) for arc_item in self.arc_items: if arc_item.scene(): arc_item.scene().removeItem(arc_item) other_item = arc_item.other_item(self) if other_item.is_wip: other_item.wipe_out() def contextMenuEvent(self, e): """Shows context menu. Args: e (QGraphicsSceneMouseEvent): Mouse event """ e.accept() if not self.isSelected() and not e.modifiers() & Qt.ControlModifier: self.scene().clearSelection() self.setSelected(True) self._show_item_context_menu_in_parent(e.screenPos()) def _show_item_context_menu_in_parent(self, pos): raise NotImplementedError()
class MonitorItem(QGraphicsRectItem, QObject): z = 0 def __init__(self, *a, **kw): data = kw.pop("data") self.name = kw.pop("name") self.window = kw.pop("window") super().__init__(0, 0, 0, 0) self.setAcceptedMouseButtons(Qt.LeftButton) self.label = QGraphicsTextItem("", self) self.bottom_edge = QGraphicsRectItem(0, 0, 0, 0, self) self.bottom_edge.setBrush(QBrush("red", Qt.SolidPattern)) self.update_visuals(data) def update_visuals(self, monitor): self.setRect(0, 0, monitor.res_x, monitor.res_y) self.setPos(monitor.pos_x, monitor.pos_y) if monitor.orientation == "normal": self.bottom_edge.setRect(0, monitor.res_y - 50, monitor.res_x, 50) elif monitor.orientation == "left": self.bottom_edge.setRect(monitor.res_x - 50, 0, 50, monitor.res_y) elif monitor.orientation == "inverted": self.bottom_edge.setRect(0, 0, monitor.res_x, 50) elif monitor.orientation == "right": self.bottom_edge.setRect(0, 0, 50, monitor.res_y) if monitor.replica_of: label_text = f"{self.name} [{','.join(monitor.replica_of)}]" else: label_text = self.name self.label.setPlainText(label_text) label_scale = min( self.rect().width() / self.label.boundingRect().width(), self.rect().height() / self.label.boundingRect().height(), ) self.label.setScale(label_scale) if monitor.enabled: if monitor.primary: color = QColor("#eee8d5") color.setAlpha(200) self.setBrush(QBrush(color, Qt.SolidPattern)) self.setZValue(1000) else: color = QColor("#ffffff") color.setAlpha(200) self.setBrush(QBrush(color, Qt.SolidPattern)) self.setZValue(self.z) self.z -= 1 self.show() else: color = QColor("#f1f1f1") color.setAlpha(200) self.setBrush(QBrush(color, Qt.SolidPattern)) self.setZValue(-1000) self.hide() def mousePressEvent(self, event): self.window.pos_label.show() self.setCursor(Qt.ClosedHandCursor) self.orig_pos = self.pos() self.window.ui.screenCombo.setCurrentText(self.name) def mouseReleaseEvent(self, event): self.setCursor(Qt.OpenHandCursor) self.window.pos_label.hide() self.window.monitor_moved() def mouseMoveEvent(self, event): snaps_x, snaps_y = self.window.possible_snaps(self.name) view = event.widget().parent() click_pos = event.buttonDownScreenPos(Qt.LeftButton) current_pos = event.screenPos() new_pos = view.mapFromScene(self.orig_pos) + current_pos - click_pos new_pos = view.mapToScene(new_pos) delta = view.mapToScene(0, 20).y() if not event.modifiers() & Qt.AltModifier: # Check for snaps x = new_pos.x() delta_x = min((abs(x - sx), i) for i, sx in enumerate(snaps_x)) if delta_x[0] < delta: # snap new_pos.setX(int(snaps_x[delta_x[1]])) y = new_pos.y() delta_y = min((abs(y - sy), i) for i, sy in enumerate(snaps_y)) if delta_y[0] < delta: # snap new_pos.setY(int(snaps_y[delta_y[1]])) self.setPos(new_pos) self.window.show_pos(int(self.pos().x()), int(self.pos().y()))
from PySide2.QtGui import (QPen, QBrush, QPolygonF) from PySide2.QtCore import (Qt, QRectF, QPoint, QPointF) import sys if __name__ == '__main__': app = QApplication(sys.argv) scene = QGraphicsScene(QRectF(-50, -50, 400, 200)) rect = QGraphicsRectItem(scene.sceneRect().adjusted(1, 1, -1, -1)) rect.setPen(QPen(Qt.red, 1)) scene.addItem(rect) rectItem = QGraphicsRectItem(QRectF(-25, 25, 200, 40)) rectItem.setPen(QPen(Qt.red, 3, Qt.DashDotLine)) rectItem.setBrush(Qt.gray) scene.addItem(rectItem) print(f'Rect Pos: {rectItem.pos()}') textItem = QGraphicsSimpleTextItem("Foundation of Qt") scene.addItem(textItem) print(f'Text Pos: {textItem.pos()}') textItem.setPos(50, 0) print(f'Text Pos: {textItem.pos()}') ellipseItem = QGraphicsEllipseItem(QRectF(170, 20, 100, 75)) ellipseItem.setPen(QPen(Qt.darkBlue)) ellipseItem.setBrush(Qt.blue) scene.addItem(ellipseItem) points = [
class QScene2dViewer(AbstractGraphicViewer): drawaxis = False axis_center = None axis_x = None axis_y = None G = None def __init__(self, G): super().__init__() self.G = G # self.setMinimunSize(400, 400) self.scale(1, -1) # AXIS self.axis_center = QGraphicsRectItem(-100, -100, 200, 200) self.axis_center.setPen(QPen(QColor("black"))) self.axis_center.setBrush(QBrush(QColor("black"))) self.axis_center.setZValue(5000) self.axis_x = QGraphicsRectItem(0, 0, 1000, 30) self.axis_x.setPen(QPen(QColor("red"))) self.axis_x.setBrush(QBrush(QColor("red"))) self.axis_x.setZValue(5000) self.axis_y = QGraphicsRectItem(0, 0, 30, 1000) self.axis_y.setPen(QPen(QColor("blue"))) self.axis_y.setBrush(QBrush(QColor("blue"))) self.axis_y.setZValue(5000) self.set_draw_axis(True) self.draw_axis() def create_graph(self): pass def set_draw_axis(self, visible): self.drawaxis = visible def draw_axis(self): if self.drawaxis: self.scene.addItem(self.axis_center) self.scene.addItem(self.axis_x) self.scene.addItem(self.axis_y) else: self.scene.removeItem(self.axis_center) self.scene.removeItem(self.axis_x) self.scene.removeItem(self.axis_y) # SLOTS def add_or_assign_node_slot(self, node_id, node_type, name=""): pass def add_or_assign_node_slot(self, node_id, node): pass def add_or_assign_edge_slot(self, from_node, to_node, node_type): pass def del_edge_slot(self, from_node, to_node, edge_tag): pass def del_node_slot(self, node_id): pass def node_change_slot(self, value, node_id, node_type, parent=None): pass def category_change_slot(self, value, parent=None): pass