class StartScene(QGraphicsScene): def __init__(self, mask_scene, stage=1): super().__init__() self.mask_scene = mask_scene self.y_list = [300, 400] self.selected = 0 self.stage = stage self.one_play_text_item = QGraphicsTextItem() self.two_plays_text_item = QGraphicsTextItem() self.indicator_item = None self.start = False self.init() def init(self): brush = QBrush() brush.setColor(Qt.black) brush.setStyle(Qt.SolidPattern) self.setBackgroundBrush(brush) font = QFont() font.setPointSize(20) font.setBold(True) self.one_play_text_item.setPlainText('One Player') self.two_plays_text_item.setPlainText('Two Players') self.one_play_text_item.setDefaultTextColor(Qt.white) self.two_plays_text_item.setDefaultTextColor(Qt.white) self.one_play_text_item.setFont(font) self.two_plays_text_item.setFont(font) self.one_play_text_item.setX(300) self.two_plays_text_item.setX(300) self.one_play_text_item.setY(self.y_list[0]) self.two_plays_text_item.setY(self.y_list[1]) self.addItem(self.one_play_text_item) self.addItem(self.two_plays_text_item) png = QPixmap() png.load('../images/%s' % TankType.PLAYER_ONE.pic) png = png.scaled(25, 25) self.indicator_item = QGraphicsPixmapItem(png) self.indicator_item.setRotation(90) self.indicator_item.setX(260) self.indicator_item.setY(self.y_list[self.selected] + 8) self.addItem(self.indicator_item) def keyPressEvent(self, event: QKeyEvent): if event.key() == Qt.Key_Up: self.selected -= 1 if self.selected < 0: self.selected = len(self.y_list) - 1 if event.key() == Qt.Key_Down: self.selected += 1 if self.selected >= len(self.y_list): self.selected = 0 self.indicator_item.setY(self.y_list[self.selected] + 8) if event.key() == Qt.Key_Space: if not self.start: self.start = True self.mask_scene.start_animation(self.selected)
def overlay_text( self, message: str, color: int, size: int, x: int, y: int, timeout: int, font_name: str, centered: bool, shadow: bool, ): gfx = QGraphicsTextItem(message) gfx.setDefaultTextColor(decode_color(color)) font = QFont(font_name, min(50, size)) font.setStyleHint(QFont.SansSerif) gfx.setFont(font) if shadow: effect = QGraphicsDropShadowEffect(gfx) effect.setBlurRadius(0) effect.setColor(Qt.GlobalColor.black) effect.setOffset(1, 1) gfx.setGraphicsEffect(effect) if centered: # The provided x, y is at the center of the text bound = gfx.boundingRect() gfx.setPos(x - (bound.width() / 2), y - (bound.height() / 2)) else: gfx.setPos(x, y) self._finalize_gfx(gfx, timeout)
def create_qr_scene(self, scene, qr_pixel_map, qr_text, backgound_pixmap) : pixmap_item = QGraphicsPixmapItem(qr_pixel_map) pixmap_item.setY(100) pixmap_item.setX(100) background_item = QGraphicsPixmapItem(backgound_pixmap) url_item = QGraphicsTextItem(qr_text) url_item.setFont(QFont('Arial', 50)) url_item.setTextWidth(820) url_item.setY(450) url_item.setX(1150) url_item.setZValue(1) pixmap_item.setZValue(1) background_item.setZValue(-1) scene.addItem(pixmap_item) scene.addItem(url_item) scene.addItem(background_item) return scene
class FilterIcon(QGraphicsEllipseItem): """An icon to show that a Link has filters.""" def __init__(self, x, y, w, h, parent): super().__init__(x, y, w, h, parent) self._parent = parent color = QColor("slateblue") self.setBrush(qApp.palette().window()) # pylint: disable=undefined-variable self._text_item = QGraphicsTextItem(self) font = QFont('Font Awesome 5 Free Solid') self._text_item.setFont(font) self._text_item.setPos(0, 0) self._text_item.setPlainText("\uf0b0") self._text_item.setDefaultTextColor(color) self._text_item.setPos(self.sceneBoundingRect().center() - self._text_item.sceneBoundingRect().center()) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=True) self.setCursor(Qt.PointingHandCursor) def itemChange(self, change, value): """Selects the parent item instead of this.""" if change == QGraphicsItem.GraphicsItemChange.ItemSelectedChange and value == 1: if not self._parent.isSelected(): self._parent.setSelected(True) return not value return super().itemChange(change, value)
def create_start_scene(self, scene, qr_pixel_map): text_item = QGraphicsTextItem("Wilkommen zur Photobox bitte den Start Button Drücken") text_item.setFont(QFont('Arial', 50)) pixmap_item = QGraphicsPixmapItem(qr_pixel_map) scene.addItem(pixmap_item) return scene
def add_human_by_pos(self, id, pos): x, y = pos human = QGraphicsEllipseItem(0, 0, 200, 200) self._scene.addItem(human) human.setBrush(QBrush(Qt.black, style=Qt.SolidPattern)) human_text = QGraphicsTextItem(str(pos)) font = QFont("Helvetica [Cronyx]", 40, QFont.Bold) human_text.setFont(font) human_text.setParentItem(human) human.setPos(pos[0], pos[1]) self._humans[id] = human human.setZValue(30)
def draw_message_text(item: QGraphicsTextItem, font: QFont, text: str, x: int, y: int, max_width: int): item.setDefaultTextColor(QColor.fromRgba(0xFF440400)) item.setFont(font) item.setPos(x, y) # Calculate how many character to trim *without* making copies of the string. font_metrics = QFontMetrics(font) cur_width = font_metrics.width(text) cur_end = len(text) - 1 while cur_width > max_width: cur_width -= font_metrics.charWidth(text, cur_end) cur_end -= 1 item.setPlainText(text[:cur_end + 1])
class FilterIcon(QGraphicsEllipseItem): """An icon to show that a Link has filters.""" def __init__(self, x, y, w, h, parent): super().__init__(x, y, w, h, parent) self._parent = parent color = QColor("slateblue") self.setBrush(qApp.palette().window()) # pylint: disable=undefined-variable self._text_item = QGraphicsTextItem(self) font = QFont('Font Awesome 5 Free Solid') self._text_item.setFont(font) self._text_item.setPos(0, 0) self._text_item.setPlainText("\uf0b0") self._text_item.setDefaultTextColor(color) self._text_item.setPos(self.sceneBoundingRect().center() - self._text_item.sceneBoundingRect().center()) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=False)
class _LinkIcon(QGraphicsEllipseItem): """An icon to show over a Link.""" def __init__(self, x, y, w, h, parent): super().__init__(x, y, w, h, parent) self._parent = parent color = QColor("slateblue") self.setBrush(qApp.palette().window()) # pylint: disable=undefined-variable self._text_item = QGraphicsTextItem(self) font = QFont('Font Awesome 5 Free Solid') self._text_item.setFont(font) self._text_item.setDefaultTextColor(color) self._svg_item = QGraphicsSvgItem(self) self._datapkg_renderer = QSvgRenderer() self._datapkg_renderer.load(":/icons/datapkg.svg") self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=False) self._block_updates = False def update_icon(self): """Sets the icon (filter, datapkg, or none), depending on Connection state.""" connection = self._parent.connection if connection.use_datapackage: self.setVisible(True) self._svg_item.setVisible(True) self._svg_item.setSharedRenderer(self._datapkg_renderer) scale = 0.8 * self.rect().width( ) / self._datapkg_renderer.defaultSize().width() self._svg_item.setScale(scale) self._svg_item.setPos(0, 0) self._svg_item.setPos(self.sceneBoundingRect().center() - self._svg_item.sceneBoundingRect().center()) self._text_item.setVisible(False) return if connection.has_filters(): self.setVisible(True) self._text_item.setVisible(True) self._text_item.setPlainText("\uf0b0") self._svg_item.setPos(0, 0) self._text_item.setPos( self.sceneBoundingRect().center() - self._text_item.sceneBoundingRect().center()) self._svg_item.setVisible(False) return self.setVisible(False) self._text_item.setVisible(False) self._svg_item.setVisible(False)
def dibujar(self): pen = QPen() brush = QBrush() pen.setWidth(3) for i in self.organizador: color = QColor(i.red, i.green, i.blue) brush.setStyle(Qt.SolidPattern) brush.setColor(color) pen.setColor(color) self.scene.addEllipse(i.or_x, i.or_y, 7, 7, pen, brush) self.scene.addEllipse(i.de_x, i.de_y, 7, 7, pen, brush) self.scene.addLine((i.or_x) + 3.5, (i.or_y) + 3.5, (i.de_x) + 3.5, (i.de_y) + 3.5, pen) for keys in self.organizador.grafo_dic: text = QGraphicsTextItem(str(keys)) text.setFlag(QGraphicsItem.ItemIsMovable) text.setFont(QFont("TimesNewRoman", 12, QFont.ExtraBold)) self.scene.addItem(text) text.setPos(keys[0], keys[1])
def add_output(self, name='output', multi_port=False, display_name=True): """ Args: name (str): name for the port. multi_port (bool): allow multiple connections. display_name (bool): display the port name. Returns: PortItem: output item widget """ port = PortItem(self) port.name = name port.port_type = OUT_PORT port.multi_connection = multi_port port.display_name = display_name text = QGraphicsTextItem(port.name, self) text.font().setPointSize(8) text.setFont(text.font()) text.setVisible(display_name) self._output_items[port] = text if self.scene(): self.post_init() return port
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 ExecutionIcon(QGraphicsEllipseItem): """An icon to show information about the item's execution.""" _CHECK = "\uf00c" _CROSS = "\uf00d" _CLOCK = "\uf017" def __init__(self, parent): """ Args: parent (ProjectItemIcon): the parent item """ super().__init__(parent) self._parent = parent self._execution_state = "not started" self._text_item = QGraphicsTextItem(self) font = QFont('Font Awesome 5 Free Solid') self._text_item.setFont(font) parent_rect = parent.rect() self.setRect(0, 0, 0.5 * parent_rect.width(), 0.5 * parent_rect.height()) self.setPen(Qt.NoPen) # pylint: disable=undefined-variable self.normal_brush = qApp.palette().window() self.selected_brush = qApp.palette().highlight() self.setBrush(self.normal_brush) self.setAcceptHoverEvents(True) self.setFlag(QGraphicsItem.ItemIsSelectable, enabled=False) self.hide() def item_name(self): return self._parent.name() def _repaint(self, text, color): self._text_item.prepareGeometryChange() self._text_item.setPos(0, 0) self._text_item.setPlainText(text) self._text_item.setDefaultTextColor(color) size = self._text_item.boundingRect().size() dim_max = max(size.width(), size.height()) rect_w = self.rect().width() self._text_item.setScale(rect_w / dim_max) self._text_item.setPos(self.sceneBoundingRect().center() - self._text_item.sceneBoundingRect().center()) self.show() def mark_execution_wating(self): self._execution_state = "waiting for dependencies" self._repaint(self._CLOCK, QColor("orange")) def mark_execution_started(self): self._execution_state = "in progress" self._repaint(self._CHECK, QColor("orange")) def mark_execution_finished(self, success, skipped): if success: self._execution_state = "skipped" if skipped else "completed" colorname = "orange" if skipped else "green" self._repaint(self._CHECK, QColor(colorname)) else: self._execution_state = "failed" self._repaint(self._CROSS, QColor("red")) def hoverEnterEvent(self, event): tip = f"<p><b>Execution {self._execution_state}</b>. Select this item to see Console and Log messages.</p>" QToolTip.showText(event.screenPos(), tip) def hoverLeaveEvent(self, event): QToolTip.hideText()
class ScaleLine: def __init__(self, parent, color, text_color, text_start="", margins=(0, 0, 0, 0), dp=1, is_upload=False): self._parent = parent self._color = color self._text_color = text_color self._text_start = text_start self._left, self._top, self._right, self._bottom = margins self._dp = dp self._is_upload = is_upload self._line = QGraphicsLineItem(self._parent) self._line.setZValue(12) pen = QPen(self._color) pen.setWidth(1) pen.setStyle(Qt.DashLine) self._line.setPen(pen) if not self._is_upload: self._text_item = QGraphicsTextItem(self._parent) self._text_item.setZValue(11) self._text_item.setDefaultTextColor(self._text_color) font = self._text_item.font() font_size = 10 * self._dp if font_size > 0: self._text_item.setFont(QFont(font.family(), font_size)) def set_line(self, max_value=0, resize=False): height = self._parent.size().height() + self._top + self._bottom shift = int(height - height / 1.1) y = -self._top + shift if not self._is_upload: value = 0 max_value = int(max_value / 1.1) megabyte = 1024 * 1024 if max_value > megabyte: value = "{} MB".format(round(max_value / megabyte, 1)) elif max_value > 1024: max_value //= 1024 if max_value >= 10: max_value = max_value // 10 * 10 value = "{} KB".format(max_value) elif max_value > 0: if max_value >= 10: max_value = max_value // 10 * 10 value = "{} B".format(max_value) scale_text = self._text_start if not value \ else "{}{}/s".format(self._text_start, value) font_height = QFontMetrics(self._text_item.font())\ .boundingRect(scale_text).height() x = 10 self._text_item.setPos(x, y - font_height - 10) self._text_item.setPlainText(scale_text) if not resize: return self._line.setLine(QLineF(0, y, self._parent.size().width() + 30, y))
def draw_message(self, text: str, name: str, window_type="standard", mode=0, left=True) -> QGraphicsItemGroup: # Create the message box talk_window: QPixmap = self.view.talk_windows[window_type][mode] message_box = self.scene.addPixmap(talk_window) talk_window_x = _TALK_WINDOW_MODE_0_X if not mode else -3 talk_window_y = _TALK_WINDOW_Y if not mode else _TALK_WINDOW_Y - 5 message_box.setPos(talk_window_x, talk_window_y) # Create the name plate name_plate_texture: QPixmap = self.view.talk_windows["name_plate"][ "plate"] name_plate = self.scene.addPixmap(name_plate_texture) name_plate_x = _NAME_PLATE_LEFT_X if left else _NAME_PLATE_RIGHT_X name_plate.setPos(name_plate_x, _NAME_PLATE_Y) # Create the name plate text name_plate_text = QGraphicsTextItem() name_plate_text.setPlainText(name) name_plate_text.setDefaultTextColor(QColor.fromRgba(0xFFFFFFB3)) name_plate_text.setFont(self.view.name_plate_font) name_plate_text.setTextWidth(name_plate_texture.width()) name_plate_text.setPos(name_plate_x, _NAME_PLATE_Y) # Center the name plate text block_format = QTextBlockFormat() block_format.setAlignment(QtGui.Qt.AlignCenter) cursor = name_plate_text.textCursor() cursor.select(QTextCursor.Document) cursor.mergeBlockFormat(block_format) cursor.clearSelection() name_plate_text.setTextCursor(cursor) self.scene.addItem(name_plate_text) # Create the message box text. Draw two lines if required. # Truncate lines with width > 312 split_text = text.split("\n") message_box_text = QGraphicsTextItem() message_box_text_2 = QGraphicsTextItem() if split_text and split_text[0]: text_utils.draw_message_text(message_box_text, self.view.name_plate_font, split_text[0], _TALK_WINDOW_MODE_0_X + 20, _TALK_WINDOW_Y + 5, 312) if len(split_text) > 1 and split_text[1]: text_utils.draw_message_text(message_box_text_2, self.view.name_plate_font, split_text[1], _TALK_WINDOW_MODE_0_X + 20, _TALK_WINDOW_Y + 21, 312) group = self.scene.createItemGroup([ message_box, message_box_text, message_box_text_2, name_plate, name_plate_text ]) group.setZValue(2.0) return group
class PortGraphics(QGraphicsItem): """ This class defines the graphics for displaying a port in the APIM View. A port is shaped somewhat like an inverted, elongated pentagon. """ REQUIRED_PEN_WIDTH = 5.0 OPTIONAL_PEN_WIDTH = 1.0 WIDTH = 50 SIDE_HEIGHT = 1.5 * WIDTH TAPER_HEIGHT = 0.5 * SIDE_HEIGHT TOTAL_HEIGHT = SIDE_HEIGHT + TAPER_HEIGHT # Center the shape about the origin of its coordinate system. X_POS = -0.5 * WIDTH Y_POS = -0.5 * TOTAL_HEIGHT PEN_COLOR = QColor(Qt.black) INNER_COLOR = QColor(100, 200, 0) OUTER_COLOR = QColor(252, 140, 3) NAME_FONT = QFont("Times", 15) TYPE_FONT = QFont("Times", 15) def __init__(self, port: 'Port', parent: QGraphicsItem = None, menuEnabled: bool = True): """ Constructs a portGraphics object for the given Port object. :param port: The port for which this graphics item represents. :type port: Port :param parent: A QGraphicsItem (probably an actionGraphics object) :type parent: QGraphicsItem :param menuEnabled: If true, a context menu will be shown on right-click. :type menuEnabled: bool """ QGraphicsItem.__init__(self, parent) self.setAcceptDrops(True) self.setFlag(QGraphicsItem.ItemIsSelectable) self._port = port self._menuEnabled = menuEnabled self.menu = PortMenu() # If port is required and it's an input, make the border thicker if not self._port.isOptional() and self._port in self._port.getAction( ).getInputPorts(): self.borderWidth = PortGraphics.REQUIRED_PEN_WIDTH else: self.borderWidth = PortGraphics.OPTIONAL_PEN_WIDTH # show port name and type if self._menuEnabled: fm = QFontMetricsF(PortGraphics.NAME_FONT) name = fm.elidedText(self._port.getName(), Qt.ElideRight, PortGraphics.SIDE_HEIGHT) self.nameItem = QGraphicsTextItem(name, self) self.nameItem.setFont(PortGraphics.NAME_FONT) self.nameItem.setRotation(90) self.nameItem.setPos(PortGraphics.WIDTH / 2 + 5, -PortGraphics.TOTAL_HEIGHT / 2) fm = QFontMetricsF(PortGraphics.TYPE_FONT) t = fm.elidedText(self._port.getDataType().__name__, Qt.ElideRight, PortGraphics.SIDE_HEIGHT) self.typeItem = QGraphicsTextItem(t, self) self.typeItem.setFont(PortGraphics.TYPE_FONT) self.typeItem.setRotation(90) self.typeItem.setPos(5, -PortGraphics.TOTAL_HEIGHT / 2) def getPort(self): """ Returns the PortGraphics' Port. :return: """ return self._port def boundingRect(self) -> QRectF: """ This pure virtual function defines the outer bounds of the item as a rectangle. :return: create the bounding of the item :rtype: QRectF """ halfPenWidth = self.borderWidth / 2 x = PortGraphics.X_POS - halfPenWidth y = PortGraphics.Y_POS - halfPenWidth actualWidth = PortGraphics.WIDTH + self.borderWidth actualHeight = PortGraphics.TOTAL_HEIGHT + self.borderWidth return QRectF(x, y, actualWidth, actualHeight) def shape(self) -> QPainterPath: """ Returns the shape of the Port as a QPainterPath. Ports are shaped like an inverted, elongated pentagon. :return: The shape of the Port as a QPainterPath. :rtype: QPainterPath """ # Create the polygon (pentagon-like shape) poly = QPolygon() poly << QPoint(PortGraphics.X_POS, PortGraphics.Y_POS) poly << QPoint(PortGraphics.X_POS + PortGraphics.WIDTH, PortGraphics.Y_POS) poly << QPoint(PortGraphics.X_POS + PortGraphics.WIDTH, PortGraphics.Y_POS + PortGraphics.SIDE_HEIGHT) poly << QPoint(0, PortGraphics.Y_POS + PortGraphics.TOTAL_HEIGHT) poly << QPoint(PortGraphics.X_POS, PortGraphics.Y_POS + PortGraphics.SIDE_HEIGHT) poly << QPoint(PortGraphics.X_POS, PortGraphics.Y_POS) path = QPainterPath() path.addPolygon(poly) return path def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: QWidget) -> None: """ Paints a port. This function is used implicitly by the QGraphicsView to render a port. :param painter: The painter to paint with. :type painter: QPainter :param option: provides style options for the item. :type option: QStyleOptionGraphicsItem :param widget: QWidget :type widget: It points to the widget that is being painted on; or make it = None. :return: None :rtype: NoneType """ pen = QPen(PortGraphics.PEN_COLOR) pen.setWidth(self.borderWidth) painter.setPen(pen) if type(self._port.getAction()) == ActionWrapper: painter.setBrush(PortGraphics.INNER_COLOR) else: painter.setBrush(PortGraphics.OUTER_COLOR) painter.drawPath(self.shape()) def contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent) -> None: """ Opens a context menu (right click menu) for the component. :param event: The event that was generated when the user right-clicked on this item. :type event: QGraphicsSceneContextMenuEvent :return: None :rtype: NoneType """ return QGraphicsItem.contextMenuEvent(event) # if not self._menuEnabled: # return QGraphicsItem.contextMenuEvent(self, event) # # self.setSelected(True) # self.menu.exec_(event.screenPos()) def mousePressEvent(self, event): event.ignore()