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
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 = [ QPointF(10, 10), QPointF(0, 90), QPointF(40, 70), QPointF(80, 110), QPointF(70, 20) ] polygonItem = QGraphicsPolygonItem(QPolygonF(points)) polygonItem.setPen(QPen(Qt.darkGreen)) polygonItem.setBrush(Qt.yellow) scene.addItem(polygonItem)
class RelationshipItem(EntityItem): """Relationship item to use with GraphViewForm.""" @property def entity_type(self): return "relationship" @property def object_class_id_list(self): return self.db_mngr.get_item( self.db_map, "relationship class", self.entity_class_id)["object_class_id_list"] @property def object_name_list(self): return self.db_mngr.get_item( self.db_map, "relationship", self.entity_id).get( "object_name_list", ",".join([ "<unnamed>" for _ in range(len(self.object_class_id_list)) ])) @property def object_id_list(self): return self.db_mngr.get_item(self.db_map, "relationship", self.entity_id).get("object_id_list") @property def db_representation(self): return dict( class_id=self.entity_class_id, id=self.entity_id, object_id_list=self.object_id_list, object_name_list=self.object_name_list, ) def _init_bg(self): extent = self._extent self._bg = QGraphicsEllipseItem(-0.5 * extent, -0.5 * extent, extent, extent, self) self._bg.setPen(Qt.NoPen) bg_color = QGuiApplication.palette().color(QPalette.Normal, QPalette.Window) bg_color.setAlphaF(0.8) self._bg_brush = QBrush(bg_color) def validate_member_objects(self): """Goes through connected object items and tries to complete the relationship.""" if not self.is_wip: return True object_id_list = [ arc_item.obj_item.entity_id for arc_item in self.arc_items ] if None in object_id_list: return True object_name_list = [ arc_item.obj_item.entity_name for arc_item in self.arc_items ] entity_id = self._graph_view_form.add_relationship( self._entity_class_id, object_id_list, object_name_list) if not entity_id: return False self.entity_id = entity_id self.become_whole() return True def move_arc_items(self, pos_diff): """Moves arc items. Args: pos_diff (QPoint) """ for item in self.arc_items: item.move_rel_item_by(pos_diff) def _make_wip_tool_tip(self): return """ <html>This is a work-in-progress <b>{0}</b> relationship.</html> """.format(self.entity_class_name) def become_whole(self): super().become_whole() self.setToolTip(self.object_name_list) for item in self.arc_items: item.become_whole() def _show_item_context_menu_in_parent(self, pos): self._graph_view_form.show_relationship_item_context_menu(pos)
class RelationshipItem(EntityItem): """Represents a relationship in the Entity graph.""" def __init__(self, spine_db_editor, x, y, extent, db_map_entity_id=None): """Initializes the item. Args: spine_db_editor (GraphViewForm): '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, relationship id """ super().__init__(spine_db_editor, x, y, extent, db_map_entity_id=db_map_entity_id) @property def entity_type(self): return "relationship" @property def object_class_id_list(self): return self.db_mngr.get_item( self.db_map, "relationship_class", self.entity_class_id)["object_class_id_list"] @property def object_name_list(self): return self.db_mngr.get_item(self.db_map, "relationship", self.entity_id)["object_name_list"] @property def object_id_list(self): return self.db_mngr.get_item(self.db_map, "relationship", self.entity_id)["object_id_list"] @property def entity_class_name(self): return self.db_mngr.get_item(self.db_map, "relationship", self.entity_id)["class_name"] @property def db_representation(self): return dict( class_id=self.entity_class_id, id=self.entity_id, object_id_list=self.object_id_list, object_name_list=self.object_name_list, ) def _make_tool_tip(self): return ( f"""<html><p style="text-align:center;">{self.entity_class_name}<br>""" f"""{self.object_name_list.replace(",", self.db_mngr._GROUP_SEP)}<br>""" f"""@{self.db_map.codename}</p></html>""") def _init_bg(self): extent = self._extent self._bg = QGraphicsEllipseItem(-0.5 * extent, -0.5 * extent, extent, extent, self) self._bg.setPen(Qt.NoPen) bg_color = QGuiApplication.palette().color(QPalette.Normal, QPalette.Window) bg_color.setAlphaF(0.8) self._bg_brush = QBrush(bg_color) def follow_object_by(self, dx, dy): factor = 1.0 / len(set(arc.obj_item for arc in self.arc_items)) self.moveBy(factor * dx, factor * dy)
class AbstractNode(AbstractGeneralGraphicsItemClass): __metaclass__ = AbstractGeneralGraphicsItem_Meta def __init__(self, graphWidget, state): super(AbstractNode, self).__init__() self.graph = weakref.ref(graphWidget) self.isAcceptable = state.isAcceptable self.isCurrent = state.isCurrent self.newPos = QPointF() self.setFlag(QGraphicsItem.ItemIsMovable) self.setFlag(QGraphicsItem.ItemIsSelectable) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) self.setCacheMode(self.DeviceCoordinateCache) self.setZValue(-1) self.setAcceptHoverEvents(True) self._edges = [] self.currentFill = self.fillQColor self.border = QGraphicsEllipseItem(-self.radius, -self.radius, self.radius * 2, self.radius * 2) self.finalNodeBorder = QGraphicsEllipseItem(-self.radius + 5, -self.radius + 5, self.radius * 2 - 10, self.radius * 2 - 10) self.finalNodeBorder.mapToParent(self.border.pos()) if self.isAcceptable == False: pen = self.finalNodeBorder.pen() pen.setColor(QColor(25, 255, 5)) self.finalNodeBorder.update() if self.isCurrent == True: self.resolveFillColor() self.labelBox = QGraphicsTextItem(self) self.labelBox.setPos(-self.radius / 2, -self.radius / 2) self.labelBox.setDefaultTextColor(QColor(0, 0, 0)) @property @abstractmethod def borderQColor(self): pass @property @abstractmethod def fillQColor(self): pass @property @abstractmethod def currentStateFillQColor(self): pass @property @abstractmethod def radius(self): pass @abstractmethod def setLabel(self, value): pass def toggleCurrentState(self): self.isCurrent = not self.isCurrent self.resolveFillColor() def resolveFillColor(self): brush = QBrush() if self.isCurrent == True: brush.setColor(self.currentStateFillQColor) brush.setStyle(Qt.SolidPattern) self.currentFill = self.currentStateFillQColor else: brush.setColor(self.fillQColor) brush.setStyle(Qt.SolidPattern) self.currentFill = self.fillQColor self.border.setBrush(brush) self.update() def toggleFinalNodeBorder(self): self.isAcceptable = not self.isAcceptable self.resolveFinalNodeBorder() def resolveFinalNodeBorder(self): pen = QPen() if self.isAcceptable == True: pen.setColor(self.borderQColor) pen.setWidth(2) else: pen.setColor(self.currentFill) pen.setWidth(1) self.finalNodeBorder.setPen(pen) self.update() def addEdge(self, edge): self._edges.append(weakref.ref(edge)) edge.adjust() def getEdges(self): return self._edges def getEdgesForInput(self, input): edges = [] for edge in self._edges: if edge.onInput == input: edges.append(edge) return edges def getEdgesFromSelf(self, input): edges = [] for edge in self._edges: if edge.onInput == input and edge.fromNode is self: edges.append(edge) return edges def getEdgeToNode(self, toNode): toReturn = None for edge in self._edges: if edge.toNode() is toNode: toReturn = edge return toReturn def boundingRect(self): adjust = 2.0 return QRectF(-self.radius - adjust, -self.radius - adjust, (self.radius + adjust) * 2, (self.radius + adjust) * 2) def shape(self): path = QtGui.QPainterPath() path.addEllipse(-self.radius, -self.radius, self.radius * 2, self.radius * 2) return path def paint(self, painter, option, widget): pen = QPen() pen.setWidth(2) pen.setColor(self.borderQColor) brush = QBrush() self.border.setPen(pen) self.border.setBrush(brush) self.resolveFillColor() self.resolveFinalNodeBorder() self.border.paint(painter, option, widget) self.finalNodeBorder.paint(painter, option, widget) self.labelBox.setTextWidth(35) self.labelBox.setDefaultTextColor(QColor(0, 0, 0)) def itemChange(self, change, value): if change == QGraphicsItem.ItemPositionChange: for edge in self._edges: edge().adjust() return QGraphicsItem.itemChange(self, change, value) def mousePressEvent(self, event): self.update() QGraphicsItem.mousePressEvent(self, event) def mouseReleaseEvent(self, event): QGraphicsItem.mouseReleaseEvent(self, event) self.update()
def eventFilter(self, obj, event): if event.type() == QEvent.GraphicsSceneMousePress: if event.button() == Qt.MouseButton.LeftButton: self.mouse_pressed = True self.mouse_pressed_x, self.mouse_pressed_y = event.pos().x( ), event.pos().y() if self.draw_ellipse: ellipsis = QGraphicsEllipseItem(self.chart) ellipsis.setZValue(12) ellipsis.setBrush(QBrush(QColor(244, 67, 54, 50))) ellipsis.setPen(QPen(Qt.transparent)) self.ellipses.append(ellipsis) elif self.write_text: for t in self.texts: r = QRectF() r.setTopLeft(t.pos()) r.setWidth(t.boundingRect().width()) r.setHeight(t.boundingRect().height()) if r.contains(self.mouse_pressed_x, self.mouse_pressed_y): return True """ The user clicked over an area where there is no text. So we create one. """ text = QGraphicsTextItem(self.chart) text.setZValue(12) text.setPos( QPointF(self.mouse_pressed_x, self.mouse_pressed_y)) text.setPlainText("label") text.setAcceptHoverEvents(True) text.setTabChangesFocus(True) text.setFlags(QGraphicsTextItem.ItemIsMovable) text.installEventFilter(self.text_event_filter) self.texts.append(text) return True elif event.button() == Qt.MouseButton.RightButton: x, y = event.pos().x(), event.pos().y() for e in self.ellipses: if e.rect().contains(x, y): e.hide() self.ellipses.remove(e) for t in self.texts: r = QRectF() r.setTopLeft(t.pos()) r.setWidth(t.boundingRect().width()) r.setHeight(t.boundingRect().height()) if r.contains(x, y): t.hide() self.texts.remove(t) return True return QObject.eventFilter(self, obj, event) elif event.type() == QEvent.GraphicsSceneMouseRelease: self.mouse_pressed = False return True elif event.type() == QEvent.GraphicsSceneMouseMove: if self.mouse_pressed: if self.draw_ellipse: x, y = event.pos().x(), event.pos().y() width = x - self.mouse_pressed_x height = y - self.mouse_pressed_y self.ellipses[-1].setRect(self.mouse_pressed_x, self.mouse_pressed_y, width, height) return True return QObject.eventFilter(self, obj, event) return QObject.eventFilter(self, obj, event)