def drawString(self, content, fontSize=256, color=QColor("red")): icon = self.icon() pixmap = icon.pixmap(512, 512) pixSize = pixmap.rect() painter = QPainter(pixmap) font = painter.font() font.setPixelSize(fontSize) painter.setFont(font) path = QPainterPath() path.addText(0, 0, font, content) pathBBox = path.boundingRect() xOffset = (pixSize.width() - pathBBox.width()) / 2 - pathBBox.left() yOffset = (pixSize.height() + pathBBox.height()) / 2 path.translate(xOffset, yOffset) ## paint shadow pathPen = QPen(QColor(0, 0, 0, 200)) pathPen.setWidth(180) painter.strokePath(path, pathPen) painter.fillPath(path, QBrush(color)) ## make number bolder pathPen = QPen(color) pathPen.setWidth(20) painter.strokePath(path, pathPen) painter.end() self.setIcon(QIcon(pixmap))
def renderImage(self, remove_useless_background=False): if not self.Image: return paintedImage = QImage(self.Image.size(), QImage.Format_ARGB32) paintedImage.fill(Qt.transparent) painter = QPainter(paintedImage) if self.cropPolygon: painterPath = QPainterPath() painterPath.addPolygon(self.cropPolygon) painter.setClipPath(painterPath) painter.drawImage(QPoint(), self.Image) # draw polygon pen = QPen(self.PolygonEdgeColor, 5) painter.setPen(pen) if len(self.polygonList): for polygon in self.polygonList: # pp = QPolygonF([QPointF(point[0], point[1]) for point in polygon['geo']]) if polygon['selected']: painter.setBrush(self.PolygonSelectedColor) else: painter.setBrush(self.PolygonColor) painter.drawPolygon(polygon['geo']) painter.end() if remove_useless_background and self.cropPolygon: return paintedImage.copy(painterPath.boundingRect().toRect()) else: return paintedImage
def updatePath(self): end_hook = self.endSocket() if end_hook is None: return self.prepareGeometryChange() end_pos = self.mapFromItem(end_hook, 0.0, 0.0) + end_hook.boundingRect().center() if self._curve: if not self._keyPoints: tangent_length = (abs(end_pos.x()) / 2.0) + (abs(end_pos.y()) / 4.0) tangent_length2 = tangent_length else: first_pos = self._keyPoints[0] tangent_length = (abs(first_pos.x()) / 2.0) + (abs(first_pos.y()) / 4.0) last_pos = self._keyPoints[-1] last_segment = end_pos - last_pos tangent_length2 = (abs(last_segment.x()) / 2.0) + (abs(last_segment.y()) / 4.0) spread = 60.0 / 180.0 * pi # Find connection index index, number_connections = self.startSocket().getIndexInfo(self) dev = (index - number_connections / 2.0 + 0.5) * min( spread, pi / (number_connections + 2)) tx = tangent_length * cos(dev) ty = tangent_length * sin(dev) start_tangent = QPointF(tx, ty) end_tangent = QPointF(end_pos.x() - tangent_length2, end_pos.y()) path = QPainterPath() path.cubicTo(start_tangent, end_tangent, end_pos) # Dot styles are used for relationships else: path = QPainterPath() path.lineTo(end_pos) stroke_width = self._pen.widthF() rect = path.boundingRect().adjusted(-stroke_width, -stroke_width, stroke_width, stroke_width) # draw widget center_widget = self._centerWidget if center_widget is not None: center = path.pointAtPercent(0.5) center_widget.onUpdated(center, text=str(self.index)) self._path = path self._rect = rect
class Segment(QGraphicsItem): def __init__(self, color, offset, parent): super(Segment, self).__init__(parent) self.color = color # 每节的身体段 self.rect = QRectF(offset, -20, 30, 40) self.path = QPainterPath() self.path.addEllipse(self.rect) # 每节的左腿 x = offset + 15 y = -20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y - 18), QPointF(x - 5, y)])) self.path.closeSubpath() # 每节的右腿 y = 20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y + 18), QPointF(x - 5, y)])) self.path.closeSubpath() self.change = 1 self.angle = 0 def boundingRect(self): return self.path.boundingRect() def shape(self): return self.path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) if option.levelOfDetailFromTransform(self.transform()) < 0.9: painter.drawEllipse(self.rect) else: painter.drawPath(self.path) def advance(self, phase): if phase == 0: matrix = self.transform() matrix.reset() self.setTransform(matrix) self.angle += self.change * random.random() if self.angle > 6: self.change = -1 # self.angle -= 0.00001 elif self.angle < -6: self.change = 1 # self.angle += 0.00001 elif phase == 1: self.setRotation(self.angle)
class Segment(QGraphicsItem): def __init__(self, color, offset, parent): super(Segment, self).__init__(parent) self.color = color self.rect = QRectF(offset, -20, 30, 40) self.path = QPainterPath() self.path.addEllipse(self.rect) x = offset + 15 y = -20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y - 12), QPointF(x - 5, y)])) self.path.closeSubpath() y = 20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y + 12), QPointF(x - 5, y)])) self.path.closeSubpath() self.change = 1 self.angle = 0 self.timer = QTimer() self.timer.timeout.connect(self.timeout) self.timer.start(INTERVAL) def boundingRect(self): return self.path.boundingRect() def shape(self): return self.path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) if option.levelOfDetailFromTransform(self.transform()) < 0.9: painter.drawEllipse(self.rect) else: painter.drawPath(self.path) def timeout(self): if not Running: return matrix = self.transform() matrix.reset() self.setTransform(matrix) self.angle += self.change * random.random() if self.angle > 4.5: self.change = -1 self.angle -= 0.00001 elif self.angle < -4.5: self.change = 1 self.angle += 0.00001 self.setRotation(self.angle)
def plotSymbol(self): sym = QPainterPath() font = QFont('Sans Serif', 10, QFont.Black) sym.addText(0, 0, font, 'o') # Scale symbol to unit square box = sym.boundingRect() scale = 1. / max(box.width(), box.height()) tr = QTransform().scale(scale, scale) # Center symbol on (0, 0) tr.translate(-box.x() - box.width() / 2., -box.y() - box.height() / 2.) return tr.map(sym)
def plotSymbol(self): """Graphical representation of an optical vortex""" sym = QPainterPath() font = QFont('Sans Serif', 10, QFont.Black) sym.addText(0, 0, font, 'V') # scale symbol to unit square box = sym.boundingRect() scale = -1./max(box.width(), box.height()) tr = QTransform().scale(scale, scale) # center symbol on (0, 0) tr.translate(-box.x() - box.width()/2., -box.y() - box.height()/2.) return tr.map(sym)
def letterSymbol(self, letter): sym = QPainterPath() font = QFont() font.setStyleHint(QFont.SansSerif, QFont.PreferAntialias) font.setPointSize(12) sym.addText(0, 0, font, letter) # Scale symbol to unit square box = sym.boundingRect() scale = 1. / max(box.width(), box.height()) tr = QTransform().scale(scale, scale) # Center symbol on (0, 0) tr.translate(-box.x() - box.width() / 2., -box.y() - box.height() / 2.) return tr.map(sym)
def renderImage(self, remove_useless_background=False): if not self.Image: return paintedImage = QImage(self.Image.size(), QImage.Format_ARGB32) paintedImage.fill(Qt.transparent) painter = QPainter(paintedImage) if self.cropPolygon: painterPath = QPainterPath() painterPath.addPolygon(self.cropPolygon) painter.setClipPath(painterPath) painter.drawImage(QPoint(), self.Image) painter.end() if remove_useless_background: return paintedImage.copy(painterPath.boundingRect().toRect()) else: return paintedImage
def draw_path(self): l, s, d = 45, 10, 10 proj = self.plan.projection.dot orig = np.array([0, 0]) axes = QPainterPath() axes.addPath(self.axis_arrow("x", orig, orig+l*proj([1, 0, 0]), s)) axes.addPath(self.axis_arrow("y", orig, orig+l*proj([0, 1, 0]), s)) axes.addPath(self.axis_arrow("z", orig, orig+l*proj([0, 0, 1]), s)) tran = self.deviceTransform(self.plan.viewportTransform()).inverted()[0] view = tran.mapRect(QRectF(self.plan.viewport().rect())) rect = axes.boundingRect() axes.translate(view.left() + view.width()/15 - rect.left(), view.bottom() - view.height()/15 - rect.bottom()) path = QPainterPath() path.addPath(axes) path.addEllipse(-d/2, -d/2, d, d) return path
def draw_path(self): l, s, d = 45, 10, 10 proj = self.plan.projection.dot orig = np.array([0, 0]) axes = QPainterPath() axes.addPath(self.axis_arrow("x", orig, orig + l * proj([1, 0, 0]), s)) axes.addPath(self.axis_arrow("y", orig, orig + l * proj([0, 1, 0]), s)) axes.addPath(self.axis_arrow("z", orig, orig + l * proj([0, 0, 1]), s)) tran = self.deviceTransform( self.plan.viewportTransform()).inverted()[0] view = tran.mapRect(QRectF(self.plan.viewport().rect())) rect = axes.boundingRect() axes.translate(view.left() + view.width() / 15 - rect.left(), view.bottom() - view.height() / 15 - rect.bottom()) path = QPainterPath() path.addPath(axes) path.addEllipse(-d / 2, -d / 2, d, d) return path
def paint(self, painter, style, widget=None): assert isinstance(painter, QPainter) if self.isSelected(): brush = QBrush(Qt.yellow) else: brush = QBrush(Qt.white) pen = QPen(Qt.black) circle_path = QPainterPath() circle_path.addEllipse(self.boundingRect()) painter.fillPath(circle_path, brush) painter.strokePath(circle_path, pen) text_path = QPainterPath() text_path.addText(0, 0, QFont(), str(self.node)) box = text_path.boundingRect() text_path.translate(-box.center()) painter.fillPath(text_path, QBrush(Qt.black))
path.quadTo(c2, start) # end def _PATH_START = QPointF(_HBW, _HBW) _PATH_MID_UP = QPointF(_HBW, -_BW) _PATH_UP_UP_CTRL_PT = QPointF(-_HBW, -_BW) _PATH_UP_DOWN_CTRL_PT = QPointF(1.5 * _BW, -_BW) _PATH_MID_DOWN = QPointF(_HBW, 2 * _BW) _PATH_DOWN_DOWN_CTRL_PT = QPointF(-_HBW, 2 * _BW) _PATH_DOWN_UP_CTRL_PT = QPointF(1.5 * _BW, 2 * _BW) _INSERT_PATH_UP = QPainterPath() _insertGen(_INSERT_PATH_UP, _PATH_START, _PATH_UP_UP_CTRL_PT,\ _PATH_MID_UP, _PATH_UP_DOWN_CTRL_PT) _INSERT_PATH_UP.translate(_OFFSET1, 0) _INSERT_PATH_UP_RECT = _INSERT_PATH_UP.boundingRect() _INSERT_PATH_DOWN = QPainterPath() _insertGen(_INSERT_PATH_DOWN, _PATH_START, _PATH_DOWN_DOWN_CTRL_PT,\ _PATH_MID_DOWN, _PATH_DOWN_UP_CTRL_PT) _INSERT_PATH_DOWN.translate(_OFFSET1, 0) _INSERT_PATH_DOWNRect = _INSERT_PATH_DOWN.boundingRect() _BIG_RECT = _DEFAULT_RECT.united(_INSERT_PATH_UP_RECT) _BIG_RECT = _BIG_RECT.united(_INSERT_PATH_DOWNRect) _B_PEN2 = getPenObj(styles.BLUE_STROKE, 2) _OFFSET2 = _BW*0.75 _FONT = QFont(styles.THE_FONT, styles.THE_FONT_SIZE/2, QFont.Bold) _BIG_RECT.adjust(-15, -15, 30, 30) # Bases are drawn along and above the insert path. # These calculations revolve around fixing the characters at a certain
class NodeTerminal(QGraphicsItem): def __init__(self, parent, cat, offset): super(NodeTerminal, self).__init__(parent) self.setFlags(QGraphicsItem.ItemIsFocusable | QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemSendsGeometryChanges) self.parent = parent # a Node self.cat = cat self.posn = self.parent.pos() self.offset = offset if self.cat == 'in': self.rect = QRectF(-5, self.offset, 10, 10) self.coords = (-5, self.offset) elif self.cat == 'out': self.rect = QRectF(95.0, self.offset, 10, 10) self.coords = (95.0, self.offset) elif self.cat == 'ins': self.rect = QRectF(45, -5, 10, 10) self.coords = (45, -5) self.path = QPainterPath() self.path.addEllipse(self.rect) self.isSelected = False self.setAcceptHoverEvents(True) self.hovered_in = False self.hovered_out = False def get_pos(self): posn = self.scenePos() x = posn.x() + self.coords[0] + 5 y = posn.y() + self.coords[1] + 5 pos = QPointF(x, y) return pos def boundingRect(self): return self.path.boundingRect() def hoverEnterEvent(self, event): try: if self.parent.parent.opt == 'wire_add': self.hovered_out = True self.update() if self.parent.parent.opt == 'wire_drag': self.hovered_in = True self.update() except AttributeError: pass def hoverLeaveEvent(self, event): self.hovered_in = False self.hovered_out = False self.update() def paint(self, painter, option, widget=None): painter.setRenderHint(QPainter.HighQualityAntialiasing) painter.setPen(Qt.black) if self.cat == 'in': if self.hovered_in: painter.setBrush(Qt.yellow) size = 15 posx = self.posn.x() - 7.5 posy = self.posn.y() + 20 else: painter.setBrush(Qt.blue) size = 10 posx = self.posn.x() - 5 posy = self.posn.y() + 22.5 #painter.drawEllipse(posx, posy, size, size) elif self.cat == 'out': if self.hovered_out: painter.setBrush(Qt.red) size = 15 posx = self.posn.x() + 92.5 posy = self.posn.y() + 20 else: painter.setBrush(QColor('#888888')) size = 10 posx = self.posn.x() + 95 posy = self.posn.y() + 22.5 #painter.drawEllipse(posx, posy, size, size) elif self.cat == 'ins': if self.hovered_in: painter.setBrush(Qt.yellow) size = 15 posx = self.posn.x() + 42.5 posy = self.posn.y() - 7.5 else: painter.setBrush(Qt.cyan) size = 10 posx = self.posn.x() + 45 posy = self.posn.y() - 5 #painter.drawEllipse(posx, posy, size, size) painter.drawPath(self.path) def drawFocusRect(self, painter): """Highlight selected""" focus_brush = QBrush() focus_pen = QPen(Qt.DotLine) focus_pen.setColor(Qt.red) focus_pen.setWidthF(1.5) painter.setBrush(focus_brush) painter.setPen(focus_pen) painter.drawRect(self.focus_rect) def mousePressEvent(self, event): #print(self.parent.name) self.isSelected = True
def svgToPath(filename): """Return QPainterPath instance from an svg file. No colors will be included. If the file contains multiple paths, they will be connected to form one single path. It will also return a boolean indicates if the path is closed or not.""" path = QPainterPath() info = findPath(filename) start = QPointF(0, 0) last_cp = start # last control point, for S cubic bezier curve. last_qp = start # last control point, for T quadratic bezier curve. for idx in range(len(info)): line = info[idx] cmd = line[0] if (cmd.upper() == 'Z'): path.closeSubpath() continue coords = re.split(r'\s+|,|(?<=\d)(?=-)', line[1]) if (cmd.upper() == 'V'): # only last coordinate matters. coord = eval(coords[-1]) verticalLineTo(path, coord, cmd) continue if (cmd.upper() == 'H'): # only last coordinate matters. coord = eval(coords[-1]) horizontalLineTo(path, coord, cmd) continue # pair two values into one coords = [x+','+y for x, y in zip(coords[::2], coords[1::2])] coords = list(map(getPoint, coords)) if (cmd.upper() == 'M'): # if m is at the start of the path if (line == info[0]): start = coords[0] moveTo(path, start, 'M') # m is not at the start of the path else: path.closeSubpath() lineTo(path, coords[0], cmd) for i in range(1, len(coords)): lineTo(path, coords[i], cmd) continue if (cmd.upper() == 'L'): for coord in coords: lineTo(path, coord, cmd) continue if (cmd.upper() == 'C'): for i in range(len(coords)//3): # Saving coordinates for smoothcurve command last_cp = cubicTo(path, *coords[i*3:i*3+3], absolute=cmd) continue if (cmd.upper() == 'S'): if not (info[idx-1][0].upper() in 'SC'): last_cp = path.currentPoint() for i in range(len(coords)//2): last_cp = smoothCubicTo(path, last_cp, *coords[i*2:i*2+2], absolute=cmd) continue if (cmd.upper() == 'Q'): for i in range(len(coords)//2): # Saving coordinates for T smooth curve command last_qp = quadTo(path, *coords[i*2:i*2+2], absolute=cmd) continue if (cmd.upper() == 'T'): if not (info[idx-1][0].upper() in 'QT'): last_qp = path.currentPoint() for coord in coords: last_qp = smoothQuadTo(path, last_qp, coord, absolute=cmd) continue raise Exception('svg file contains command {}, which is not supported' .format(cmd)) closed = True if ((abs((path.currentPosition() - start).x()) > 1) and (abs((path.currentPosition() - start).y()) > 1)): closed = False path.translate(-start) path.translate(-path.boundingRect().center()) return path, closed
class BorderItem(QGraphicsObject): def __init__(self, scene, view_scale, shape, transform=QTransform(), parent=None): super(BorderItem, self).__init__(parent) self.setTransform(transform) self.shape = shape self._item_path = QPainterPath(QPoint(0, 0)) self._pen = QPen() self._pen.setWidthF(adjust_pen_width(PEN_STANDARD_WIDTH, view_scale)) # 设置蚂蚁线数据 self._line_len = 4 self._line_step = .2 self._line_speed = 100 self._line_color = Qt.black # 线条的长度 self._dashes = 4 # 空白长度 self._spaces = 10 self._dash_pattern = [self._line_len] * 20 self._timer = QTimer() self._timer.timeout.connect(self.update_value) if scene: scene.clearSelection() scene.addItem(self) def is_empty(self): return self._item_path.isEmpty() def get_path(self): return self._item_path def get_scene_path(self): return self.mapToScene(self.get_path()) def copy(self): new_item = SelectionItem(position=self.scenePos(), scene=None, view_scale=1, path=self._item_path, shape=self.get_shape(), transform=self.transform(), parent=self.parent()) new_item.pen = self.pen return new_item def set_item_path_by_size(self, width=0, height=0): self._item_path = QPainterPath(QPoint(0, 0)) self._item_path.addRect(QRectF(0, 0, width, height)) self.update(self.boundingRect()) def set_item_path_by_path(self, path): self._item_path = path def set_pen_width_by_scale(self, width: [int, float]): pen_width = adjust_pen_width(PEN_STANDARD_WIDTH, width) self._pen.setWidthF(pen_width) def set_pen_width_by_width(self, width: [int, float]): if isinstance(width, int): self._pen.setWidth(width) elif isinstance(width, float): self._pen.setWidthF(width) @property def pen(self): return self._pen @pen.setter def pen(self, new_pen: QPen): self._pen = new_pen def update_value(self): """""" if self._dashes >= self._line_len and self._spaces >= self._line_len: self._dashes = self._spaces = 0. if self._dashes <= 0 and self._spaces < self._line_len: self._spaces += self._line_step elif self._dashes < self._line_len <= self._spaces: self._dashes += self._line_step self._dash_pattern[0] = self._dashes self._dash_pattern[1] = self._spaces self.update(self.boundingRect()) def add_area(self, path: QPainterPath): """TODO""" def cut_area(self, path: QPainterPath): """TODO""" def combine_area(self, path: QPainterPath): """TODO""" def intersects(self, other) -> bool: p1 = self.mapToScene(self.get_path()) p2 = other.mapToScene(other.get_path()) return p1.intersects(p2) def shape(self): return self._item_path # 继承QGraphicsItem类必须实现 boundingRect() paint()两个方法 # 返回本item的 包围和矩形 QRectF 用于item的点击等判断 def boundingRect(self): return self._item_path.boundingRect().adjusted(0, 0, 2, 2) def paint(self, painter: QPainter, option, widget=None) -> None: self._pen.setColor(Qt.white) self._pen.setStyle(Qt.SolidLine) painter.setPen(self._pen) painter.drawPath(self._item_path) self._pen.setColor(Qt.black) self._pen.setDashPattern(self._dash_pattern) painter.setPen(self._pen) painter.drawPath(self._item_path) def __add__(self, other): """ 轮廓 +operation :param other: :return: self """ p1 = self.mapToScene(self._item_path) p2 = other.mapToScene(other.get_path()) new_path = self.mapFromScene(p1 + p2) new_item = self.copy() new_item.set_item_path_by_path(new_path) return new_item def __iadd__(self, other): """ 轮廓 +=operation :param other: :return: self """ p1 = self.mapToScene(self._item_path) p2 = other.mapToScene(other.get_path()) new_path = self.mapFromScene(p1 + p2) new_path.closeSubpath() self._item_path = new_path return self def __sub__(self, other): """ 轮廓 -operation :param other: :return: self """ p1 = self.mapToScene(self._item_path) p2 = other.mapToScene(other.get_path()) new_path = self.mapFromScene(p1 - p2) new_path.closeSubpath() new_item = self.copy() new_item.set_item_path_by_path(new_path) return new_item def __isub__(self, other): """ 轮廓 -=operation :param other: :return: self """ p1 = self.mapToScene(self._item_path) p2 = other.mapToScene(other.get_path()) new_path = self.mapFromScene(p1 - p2) new_path.closeSubpath() self._item_path = new_path self.update() return self def __and__(self, other): """ 轮廓 &operation :param other: :return: self """ p1 = self.mapToScene(self._item_path) p2 = other.mapToScene(other.get_path()) new_path = self.mapFromScene(p1 & p2) new_path.closeSubpath() new_item = self.copy() new_item.set_item_path_by_path(new_path) return new_item def __iand__(self, other): """ 轮廓 &=operation :param other: :return: self """ p1 = self.mapToScene(self._item_path) p2 = other.mapToScene(other.get_path()) self._item_path = self.mapFromScene(p1 & p2) self._item_path.closeSubpath() self.update() return self
class StMoveGUI(QGraphicsLineItem, StMove): def __init__(self, shape): QGraphicsLineItem.__init__(self) StMove.__init__(self, shape) self.allwaysshow = False self.path = QPainterPath() self.setFlag(QGraphicsItem.ItemIsSelectable, False) self.pen = QPen(QColor(50, 100, 255), 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin) self.pen.setCosmetic(True) self.make_papath() def contains_point(self, point): """ StMove cannot be selected. Return maximal distance """ return float(0x7fffffff) def make_papath(self): """ To be called if a Shape shall be printed to the canvas @param canvas: The canvas to be printed in @param pospro: The color of the shape """ start = self.geos.abs_el(0).get_start_end_points(True) self.path = QPainterPath() self.path.moveTo(start.x, -start.y) drawHorLine = lambda caller, start, end: self.path.lineTo(end.x, -end.y) drawVerLine = lambda caller, start: None # Not used in 2D mode self.make_path(drawHorLine, drawVerLine) def setSelected(self, flag=True): """ Override inherited function to turn off selection of Arrows. @param flag: The flag to enable or disable Selection """ if self.allwaysshow: pass elif flag is True: self.show() else: self.hide() def setallwaysshow(self, flag=False): """ If the directions shall be allwaysshown the parameter will be set and all paths will be shown. @param flag: The flag to enable or disable Selection """ self.allwaysshow = flag if flag is True: self.show() elif flag is True and self.isSelected(): self.show() else: self.hide() def paint(self, painter, option, widget=None): """ Method will be triggered with each paint event. Possible to give options @param painter: Reference to std. painter @param option: Possible options here @param widget: The widget which is painted on. """ painter.setPen(self.pen) painter.drawPath(self.path) def boundingRect(self): """ Required method for painting. Inherited by Painterpath @return: Gives the Bounding Box """ return self.path.boundingRect()
path.quadTo(c2, start) # end def _PATH_START = QPointF(_HBW, _HBW) _PATH_MID_UP = QPointF(_HBW, -_BW) _PATH_UP_UP_CTRL_PT = QPointF(-_HBW, -_BW) _PATH_UP_DOWN_CTRL_PT = QPointF(1.5 * _BW, -_BW) _PATH_MID_DOWN = QPointF(_HBW, 2 * _BW) _PATH_DOWN_DOWN_CTRL_PT = QPointF(-_HBW, 2 * _BW) _PATH_DOWN_UP_CTRL_PT = QPointF(1.5 * _BW, 2 * _BW) _INSERT_PATH_UP = QPainterPath() _insertGen(_INSERT_PATH_UP, _PATH_START, _PATH_UP_UP_CTRL_PT, _PATH_MID_UP, _PATH_UP_DOWN_CTRL_PT) _INSERT_PATH_UP.translate(_OFFSET1, 0) _INSERT_PATH_UP_RECT = _INSERT_PATH_UP.boundingRect() _INSERT_PATH_DOWN = QPainterPath() _insertGen(_INSERT_PATH_DOWN, _PATH_START, _PATH_DOWN_DOWN_CTRL_PT, _PATH_MID_DOWN, _PATH_DOWN_UP_CTRL_PT) _INSERT_PATH_DOWN.translate(_OFFSET1, 0) _INSERT_PATH_DOWNRect = _INSERT_PATH_DOWN.boundingRect() _BIG_RECT = _DEFAULT_RECT.united(_INSERT_PATH_UP_RECT) _BIG_RECT = _BIG_RECT.united(_INSERT_PATH_DOWNRect) _B_PEN2 = getPenObj(styles.BLUE_STROKE, 2) _OFFSET2 = _BW*0.75 _FONT = QFont(styles.THE_FONT, styles.THE_FONT_SIZE/2, QFont.Bold) _BIG_RECT.adjust(-15, -15, 30, 30) # Bases are drawn along and above the insert path. # These calculations revolve around fixing the characters at a certain
class BrowserGEdge(QGraphicsItem): Type = QGraphicsItem.UserType + 2 def __init__(self, edge_record, g_node_a, g_node_b, change_manager): super(BrowserGEdge, self).__init__() # attributes self.edge_record = edge_record self.g_node_a = g_node_a self.g_node_b = g_node_b self.change_manager = change_manager # graphicsItem mode self.setFlag(QGraphicsItem.ItemIsSelectable) self.setAcceptHoverEvents(True) def set_position(self): self.p1 = self.mapFromItem(self.g_node_a, 0, 0) self.p2 = self.mapFromItem(self.g_node_b, 0, 0) # the path region for mouse detection self.edge_path = QPainterPath(self.p1) self.edge_path.lineTo(self.p2) self.prepareGeometryChange() def type(self): return BrowserGEdge.Type def boundingRect(self): extra = 10 return self.edge_path.boundingRect().adjusted(-extra, -extra, extra, extra) def shape(self): # note: path without stroker includes concave shape, not just edge path return self.edge_path def paint(self, painter, option, widget): # paint edge shape of path without brush fill line_width = 2 if option.state & QStyle.State_MouseOver: line_color = Qt.red else: line_color = Qt.blue painter.strokePath( self.edge_path, QPen(line_color, line_width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) def hoverEnterEvent(self, event): self.change_manager.signal_edge_hovered.emit(self.edge_record, self.g_node_a.node_record, self.g_node_b.node_record) super(BrowserGEdge, self).hoverEnterEvent(event) def mousePressEvent(self, event): self.change_manager.edge_selected_event(self.edge_record, self.g_node_a.node_record, self.g_node_b.node_record) super(BrowserGEdge, self).mousePressEvent(event)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setupUi(self) points = [(0, 0), (-6.6572836, 4.361927), (-9.2177166, 7.340494), (-2.2137959, 2.5753221), (-4.66601534, 6.1499951), (-4.81185534, 9.5429151), (-0.070593, 1.642318), (1.35985124, 3.843193), (2.70403794, 4.203864), (3.9058194, 1.048006), (7.699405, -2.258071), (11.636839, -2.220768), (4.653883, 0.04409), (8.669976, 4.329893), (13.502289, 2.931417), (7.08685, -2.050941), (17.480776, -9.315182), (14.745917, -16.1672141), (-0.308121, -0.771981), (-2.309601, -0.355324), (-2.309601, -0.355324)] points = [QPointF(*p) * 10 for p in points] path = QPainterPath() ref_p = QPointF(14.1681, 0.2321) * 10 path.moveTo(ref_p) for i in range(0, len(points) - 2, 3): ep = points[i + 2] + ref_p c1 = points[i] + ref_p c2 = points[i + 1] + ref_p path.cubicTo(c1, c2, ep) ref_p = ep rect = path.boundingRect().adjusted(-5, -5, 5, 5) pen_styles = { k: getattr(Qt, k) for k in dir(Qt) if isinstance(getattr(Qt, k), Qt.PenStyle) } for name, style in sorted(pen_styles.items(), key=lambda x: x[1]): if "PenStyle" in name or "Custom" in name or "NoPen" in name: continue item = QListWidgetItem(name) item.setData(PenParametersDialog.PenStyleRole, style) pixmap = QPixmap(int(rect.width()), int(rect.height())) pixmap.fill(Qt.transparent) painter = QPainter() painter.begin(pixmap) painter.setPen(QPen(Qt.darkGreen, 10, style)) painter.drawPath(path) painter.end() item.setIcon(QIcon(pixmap)) self.lstPenStyles.addItem(item) colors = { k: getattr(Qt, k) for k in dir(Qt) if isinstance(getattr(Qt, k), Qt.GlobalColor) } for name, color in sorted(colors.items(), key=lambda x: x[1]): if "color" in name or name == "transparent": continue item = QListWidgetItem(name) item.setData(PenParametersDialog.ColorRole, color) pixmap = QPixmap(100, 25) painter = QPainter() painter.begin(pixmap) painter.setBrush(color) painter.drawRect(pixmap.rect()) painter.end() item.setIcon(QIcon(pixmap)) self.lstPenColors.addItem(item)
# end def _pathStart = QPointF(_hbw, _hbw) _pathMidUp = QPointF(_hbw, -_bw) _pathUpUpCtrlPt = QPointF(-_hbw, -_bw) _pathUpDownCtrlPt = QPointF(1.5 * _bw, -_bw) _pathMidDown = QPointF(_hbw, 2 * _bw) _pathDownDownCtrlPt = QPointF(-_hbw, 2 * _bw) _pathDownUpCtrlPt = QPointF(1.5 * _bw, 2 * _bw) _insertPathUp = QPainterPath() _insertGen(_insertPathUp, _pathStart, _pathUpUpCtrlPt,\ _pathMidUp, _pathUpDownCtrlPt) _insertPathUp.translate(_offset1, 0) _insertPathUpRect = _insertPathUp.boundingRect() _insertPathDown = QPainterPath() _insertGen(_insertPathDown, _pathStart, _pathDownDownCtrlPt,\ _pathMidDown, _pathDownUpCtrlPt) _insertPathDown.translate(_offset1, 0) _insertPathDownRect = _insertPathDown.boundingRect() _bigRect = _defaultRect.united(_insertPathUpRect) _bigRect = _bigRect.united(_insertPathDownRect) _bpen2 = QPen(styles.BLUE_STROKE, 2) _offset2 = _bw * 0.75 _font = QFont(styles.THE_FONT, 10, QFont.Bold) _bigRect.adjust(-15, -15, 30, 30) # Bases are drawn along and above the insert path. # These calculations revolve around fixing the characters at a certain # percentage of the total arclength.
class StMoveGUI(QGraphicsLineItem, StMove): def __init__(self, shape): QGraphicsLineItem.__init__(self) StMove.__init__(self, shape) self.allwaysshow = False self.path = QPainterPath() self.setFlag(QGraphicsItem.ItemIsSelectable, False) self.pen = QPen(QColor(50, 100, 255), 1, QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin) self.pen.setCosmetic(True) self.make_papath() def contains_point(self, point): """ StMove cannot be selected. Return maximal distance """ return float(0x7fffffff) def make_papath(self): """ To be called if a Shape shall be printed to the canvas @param canvas: The canvas to be printed in @param pospro: The color of the shape """ self.path = QPainterPath() if len(self.geos): start = self.geos.abs_el(0).get_start_end_points(True) self.path.moveTo(start.x, -start.y) drawHorLine = lambda caller, start, end: self.path.lineTo( end.x, -end.y) drawVerLine = lambda caller, start: None # Not used in 2D mode self.make_path(drawHorLine, drawVerLine) def setSelected(self, flag=True): """ Override inherited function to turn off selection of Arrows. @param flag: The flag to enable or disable Selection """ if self.allwaysshow: pass elif flag is True: self.show() else: self.hide() def setallwaysshow(self, flag=False): """ If the directions shall be allwaysshown the parameter will be set and all paths will be shown. @param flag: The flag to enable or disable Selection """ self.allwaysshow = flag if flag is True: self.show() elif flag is True and self.isSelected(): self.show() else: self.hide() def paint(self, painter, option, widget=None): """ Method will be triggered with each paint event. Possible to give options @param painter: Reference to std. painter @param option: Possible options here @param widget: The widget which is painted on. """ painter.setPen(self.pen) painter.drawPath(self.path) def boundingRect(self): """ Required method for painting. Inherited by Painterpath @return: Gives the Bounding Box """ return self.path.boundingRect()
def updateGeometry(self): # Calculate path absolute branch_abs = QPainterPath() branch_abs.moveTo(self.__start) branch_abs.cubicTo(self.__spline1, self.__spline2, self.__end) branch_middle = self.__get_bezier_middle(branch_abs) middle_angle = self.__get_bezier_middle_angle(branch_abs) # Calculate arrow absolute arrow_abs = self.__calculate_arrow( branch_middle, middle_angle, self.__arrow_height, self.__arrow_length, self.__arrow_side_spline_depth, self.__arrow_back_spline_depth) # Calculate arrow mask absolute arrow_mask_abs = self.__calculate_arrow( branch_middle, middle_angle, self.__arrow_height + self.__arrow_mask_height_offset, self.__arrow_length + self.__arrow_mask_length_offset, self.__arrow_side_spline_depth, self.__arrow_back_spline_depth) # Add some margin to avoid cutting off anti aliasing pixels of branch branch_aliasing_margin = 4 geo_branch = branch_abs.boundingRect() \ .toRect().marginsAdded(QMargins( branch_aliasing_margin, branch_aliasing_margin, branch_aliasing_margin, branch_aliasing_margin)) # Get bounding rect of arrow mask # The mask already has a margin to avoid cuttin of anti aliasing pixels geo_arrow_mask = arrow_mask_abs.boundingRect().toRect() # Unite arrow mask bounds and branch bounds and set as geometry united = geo_branch.united(geo_arrow_mask) self.setGeometry(united) super().updateGeometry() # Translate absolute paths to relative paths for use in widget offset = self.mapFromParent(QPoint()) path_rel = QPainterPath(branch_abs) path_rel.translate(offset) self.__branch = path_rel arrow_rel = QPainterPath(arrow_abs) arrow_rel.translate(offset) self.__arrow = arrow_rel arrow_mask_rel = QPainterPath(arrow_mask_abs) arrow_mask_rel.translate(offset) self.__arrow_mask = arrow_mask_rel stroker = QPainterPathStroker() stroker.setWidth(8) wide_stroke = stroker.createStroke(self.__branch) stroker.setWidth(self.__pen_width) narrow_stroke = stroker.createStroke(self.__branch) branch_outlet = wide_stroke.united(narrow_stroke).toFillPolygon() mask_poly_f = self.__arrow_mask.toFillPolygon().united(branch_outlet) region = QRegion(mask_poly_f.toPolygon()) self.setMask(region) self.update()
path.quadTo(c2, start) # end def _pathStart = QPointF(_hbw, _hbw) _pathMidUp = QPointF(_hbw, -_bw) _pathUpUpCtrlPt = QPointF(-_hbw, -_bw) _pathUpDownCtrlPt = QPointF(1.5 * _bw, -_bw) _pathMidDown = QPointF(_hbw, 2 * _bw) _pathDownDownCtrlPt = QPointF(-_hbw, 2 * _bw) _pathDownUpCtrlPt = QPointF(1.5 * _bw, 2 * _bw) _insertPathUp = QPainterPath() _insertGen(_insertPathUp, _pathStart, _pathUpUpCtrlPt,\ _pathMidUp, _pathUpDownCtrlPt) _insertPathUp.translate(_offset1, 0) _insertPathUpRect = _insertPathUp.boundingRect() _insertPathDown = QPainterPath() _insertGen(_insertPathDown, _pathStart, _pathDownDownCtrlPt,\ _pathMidDown, _pathDownUpCtrlPt) _insertPathDown.translate(_offset1, 0) _insertPathDownRect = _insertPathDown.boundingRect() _bigRect = _defaultRect.united(_insertPathUpRect) _bigRect = _bigRect.united(_insertPathDownRect) _bpen2 = QPen(styles.BLUE_STROKE, 2) _offset2 = _bw*0.75 _font = QFont(styles.THE_FONT, 10, QFont.Bold) _bigRect.adjust(-15, -15, 30, 30) # Bases are drawn along and above the insert path. # These calculations revolve around fixing the characters at a certain
def _updatePath(self, strand5p): """ Draws a quad curve from the edge of the fromBase to the top or bottom of the toBase (q5), and finally to the center of the toBase (toBaseEndpoint). If floatPos!=None, this is a floatingXover and floatPos is the destination point (where the mouse is) while toHelix, toIndex are potentially None and represent the base at floatPos. """ group = self.group() self.tempReparent() node3 = self._node3 node5 = self._node5 bw = _BASE_WIDTH parent = self.partItem() vhi5 = self._virtual_helix_item pt5 = vhi5.mapToItem(parent, *node5.point()) five_is_top = node5.isOnTop() five_is_5to3 = node5.isDrawn5to3() vhi3 = node3.virtualHelixItem() pt3 = vhi3.mapToItem(parent, *node3.point()) three_is_top = node3.isOnTop() three_is_5to3 = node3.isDrawn5to3() same_strand = (node5.strandType() == node3.strandType()) and vhi3 == vhi5 same_parity = five_is_5to3 == three_is_5to3 # Enter/exit are relative to the direction that the path travels # overall. five_enter_pt = pt5 + QPointF(0 if five_is_5to3 else 1, 0.5) * bw five_center_pt = pt5 + QPointF(0.5, 0.5) * bw five_exit_pt = pt5 + QPointF(0.5, 0 if five_is_top else 1) * bw three_enter_pt = pt3 + QPointF(0.5, 0 if three_is_top else 1) * bw three_center_pt = pt3 + QPointF(0.5, 0.5) * bw three_exit_pt = pt3 + QPointF(1 if three_is_5to3 else 0, 0.5) * bw c1 = QPointF() # case 1: same strand if same_strand: dx = abs(three_enter_pt.x() - five_exit_pt.x()) c1.setX(0.5 * (five_exit_pt.x() + three_enter_pt.x())) if five_is_top: c1.setY(five_exit_pt.y() - _Y_SCALE * dx) else: c1.setY(five_exit_pt.y() + _Y_SCALE * dx) # case 2: same parity elif same_parity: dy = abs(three_enter_pt.y() - five_exit_pt.y()) c1.setX(five_exit_pt.x() + _X_SCALE * dy) c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y())) # case 3: different parity else: if five_is_top and five_is_5to3: c1.setX(five_exit_pt.x() - _X_SCALE * abs(three_enter_pt.y() - five_exit_pt.y())) else: c1.setX(five_exit_pt.x() + _X_SCALE * abs(three_enter_pt.y() - five_exit_pt.y())) c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y())) # Construct painter path painterpath = QPainterPath() painterpath.moveTo(five_enter_pt) painterpath.lineTo(five_center_pt) painterpath.lineTo(five_exit_pt) # The xover5's non-crossing-over end (3') has a connection painterpath.quadTo(c1, three_enter_pt) painterpath.lineTo(three_center_pt) painterpath.lineTo(three_exit_pt) tempR = painterpath.boundingRect() tempR.adjust(-bw / 2, 0, bw, 0) self._click_area.setRect(tempR) self.setPath(painterpath) node3.updatePositionAndAppearance() node5.updatePositionAndAppearance() if group: group.addToGroup(self) self._updateColor(strand5p)
class RouteText(QGraphicsItem): def __init__(self, text='S', startp=Point(x=0.0, y=0.0),): """ Initialisation of the class. """ QGraphicsItem.__init__(self) self.setFlag(QGraphicsItem.ItemIsSelectable, False) self.text = text self.sc = 1.0 self.startp = QtCore.QPointF(startp.x, -startp.y) pencolor = QColor(0, 200, 255) self.brush = QColor(0, 100, 255) self.pen = QPen(pencolor, 1, QtCore.Qt.SolidLine) self.pen.setCosmetic(True) self.path = QPainterPath() self.path.addText(QtCore.QPointF(0, 0), QFont("Arial", 10/self.sc), self.text) def contains_point(self, point): """ Text cannot be selected. Return maximal distance """ return float(0x7fffffff) def setSelected(self, *args): """ Override inherited function - with possibility to be called with multiple arguments """ def paint(self, painter, option, widget=None): """ Method for painting the arrow. """ demat = painter.deviceTransform() self.sc = demat.m11() # painter.setClipRect(self.boundingRect()) painter.setPen(self.pen) painter.setBrush(self.brush) painter.scale(1/self.sc, 1/self.sc) painter.translate(self.startp.x() * self.sc, self.startp.y() * self.sc) painter.drawPath(self.path) def shape(self): """ Reimplemented function to select outline only. @return: Returns the Outline only """ logger.debug("Hier sollte ich nicht sein") return super(RouteText, self).shape() def boundingRect(self): """ Required method for painting. Inherited by Painterpath @return: Gives the Bounding Box """ rect = self.path.boundingRect().getRect() newrect = QtCore.QRectF(self.startp.x()+rect[0]/self.sc, self.startp.y()+rect[1]/self.sc, rect[2]/self.sc, rect[3]/self.sc) return newrect
def _updatePath(self, strand5p): """ Draws a quad curve from the edge of the fromBase to the top or bottom of the toBase (q5), and finally to the center of the toBase (toBaseEndpoint). If floatPos!=None, this is a floatingXover and floatPos is the destination point (where the mouse is) while toHelix, toIndex are potentially None and represent the base at floatPos. Args: strand5p (TYPE): Description """ group = self.group() self.tempReparent() node3 = self._node3 node5 = self._node5 bw = _BASE_WIDTH parent = self.partItem() vhi5 = self._virtual_helix_item pt5 = vhi5.mapToItem(parent, *node5.point()) n5_is_forward = node5.is_forward vhi3 = node3.virtualHelixItem() pt3 = vhi3.mapToItem(parent, *node3.point()) n3_is_forward = node3.is_forward same_strand = (n5_is_forward == n3_is_forward) and (vhi3 == vhi5) same_parity = n5_is_forward == n3_is_forward # Enter/exit are relative to the direction that the path travels # overall. five_enter_pt = pt5 + QPointF(0 if n5_is_forward else 1, .5) * bw five_center_pt = pt5 + QPointF(.5, .5) * bw # five_exit_pt = pt5 + QPointF(.85 if n5_is_forward else .15, 0 if n5_is_forward else 1)*bw five_exit_pt = pt5 + QPointF(.5 if n5_is_forward else .5, 0 if n5_is_forward else 1) * bw # three_enter_pt = pt3 + QPointF(.15 if n3_is_forward else .85, 0 if n3_is_forward else 1)*bw three_enter_pt = pt3 + QPointF(.5 if n3_is_forward else .5, 0 if n3_is_forward else 1) * bw three_center_pt = pt3 + QPointF(.5, .5) * bw three_exit_pt = pt3 + QPointF(1 if n3_is_forward else 0, .5) * bw c1 = QPointF() # case 1: same strand if same_strand: dx = abs(three_enter_pt.x() - five_exit_pt.x()) c1.setX(0.5 * (five_exit_pt.x() + three_enter_pt.x())) if n5_is_forward: c1.setY(five_exit_pt.y() - _Y_SCALE * dx) else: c1.setY(five_exit_pt.y() + _Y_SCALE * dx) # case 2: same parity elif same_parity: dy = abs(three_enter_pt.y() - five_exit_pt.y()) c1.setX(five_exit_pt.x() + _X_SCALE * dy) c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y())) # case 3: different parity else: if n5_is_forward: c1.setX(five_exit_pt.x() - _X_SCALE * abs(three_enter_pt.y() - five_exit_pt.y())) else: c1.setX(five_exit_pt.x() + _X_SCALE * abs(three_enter_pt.y() - five_exit_pt.y())) c1.setY(0.5 * (five_exit_pt.y() + three_enter_pt.y())) # Construct painter path painterpath = QPainterPath() painterpath.moveTo(five_enter_pt) painterpath.lineTo(five_center_pt) painterpath.lineTo(five_exit_pt) # The xover5's non-crossing-over end (3') has a connection painterpath.quadTo(c1, three_enter_pt) painterpath.lineTo(three_center_pt) painterpath.lineTo(three_exit_pt) tempR = painterpath.boundingRect() tempR.adjust(-bw / 2, 0, bw, 0) self._click_area.setRect(tempR) self.setPath(painterpath) node3.updatePositionAndAppearance() node5.updatePositionAndAppearance() if group: group.addToGroup(self) self._updateColor(strand5p)
def paintEvent(self,event): global monster_data global dmg painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.drawPixmap(event.rect(),self.pixmap) if self.card is not None and self.card.ID is not 0: card = self.card # Draw card level at the bottom centered pen = QPen() if np.floor(card.lv) == monster_data[card.ID]['max_level']: lvstr = 'Lv.Max' brush = QBrush(QColor(252,232,131)) else: lvstr = 'Lv.%d' % np.floor(card.lv) brush = QBrush(Qt.white) path = QPainterPath() pen.setWidth(0); pen.setBrush(Qt.black) font = QFont() font.setPointSize(11) font.setWeight(QFont.Black) path.addText(event.rect().x(),event.rect().y()+48,font,lvstr) rect = path.boundingRect() target = (event.rect().x()+event.rect().width())/2 # center the rect in event.rect() path.translate(target-rect.center().x(), 0) painter.setPen(pen) painter.setBrush(QBrush(Qt.black)) painter.drawPath(path.translated(.5,.5)) painter.setPen(pen) painter.setBrush(brush) painter.drawPath(path) # Draw +eggs at the top right eggs = card.plus_atk+card.plus_hp+card.plus_rcv if eggs > 0: eggstr = '+%d' % eggs pen.setBrush(Qt.yellow) brush = QBrush(Qt.yellow) path = QPainterPath() pen.setWidth(0) pen.setBrush(Qt.black) font = QFont() font.setPointSize(11) font.setWeight(QFont.Black) path.addText(event.rect().x(),event.rect().y()+12,font,eggstr) path.translate(50-path.boundingRect().right()-3,0) #painter.setFont(font) painter.setPen(pen) painter.setBrush(QBrush(Qt.black)) painter.drawPath(path.translated(.5,.5)) painter.setPen(pen) painter.setBrush(brush) painter.drawPath(path) #painter.drawText(event.rect().adjusted(0,0,0,0),Qt.AlignRight, eggstr) # Draw awakenings at the top left in a green circle if card.current_awakening > 0: path = QPainterPath() rect = QRectF(event.rect()).adjusted(4,4,-36,-36) path.addEllipse(rect) painter.setBrush(QBrush(QColor(34,139,34))) pen.setBrush(Qt.white) pen.setWidth(1) painter.setPen(pen) painter.drawPath(path) path = QPainterPath() font.setPointSize(9) awkstr = ('%d' % card.current_awakening if card.current_awakening < card.max_awakening else '★') path.addText(rect.x(),rect.bottom(),font,awkstr) br = path.boundingRect() path.translate(rect.center().x()-br.center().x(), rect.center().y()-br.center().y()) pen.setBrush(QColor(0,0,0,0)) pen.setWidth(0) painter.setPen(pen) painter.setBrush(QBrush(Qt.yellow)) painter.drawPath(path) # Draw main attack damage #print(self.main_attack) if self.main_attack > 0: matkstr = '%d' % self.main_attack painter.setBrush(QBrush(COLORS[self.card.element[0]])) path = QPainterPath() font = QFont() font.setFamily('Helvetica') font.setWeight(QFont.Black) #font.setStretch(25) font.setPointSize(13) path.addText(rect.x(),rect.bottom(),font,matkstr) rect = QRectF(event.rect()) br = path.boundingRect() path.translate(rect.center().x()-br.center().x(), rect.center().y()-br.bottom()-1) # pen.setBrush(Qt.black) pen.setWidthF(.75) painter.setPen(pen) painter.drawPath(path) # Draw sub attack damage #print(self.main_attack) if self.sub_attack > 0: satkstr = '%d' % self.sub_attack painter.setBrush(QBrush(COLORS[self.card.element[1]])) path = QPainterPath() font = QFont() font.setFamily('Helvetica') font.setWeight(QFont.Black) #font.setStretch(25) font.setPointSize(12) path.addText(rect.x(),rect.bottom(),font,satkstr) rect = QRectF(event.rect()) br = path.boundingRect() path.translate(rect.center().x()-br.center().x(), rect.center().y()-br.top()+1) # pen.setBrush(Qt.black) pen.setWidthF(.75) painter.setPen(pen) painter.drawPath(path)
class RouteText(QGraphicsItem): def __init__( self, text='S', startp=Point(x=0.0, y=0.0), ): """ Initialisation of the class. """ QGraphicsItem.__init__(self) self.setFlag(QGraphicsItem.ItemIsSelectable, False) self.text = text self.sc = 1.0 self.startp = QtCore.QPointF(startp.x, -startp.y) pencolor = QColor(0, 200, 255) self.brush = QColor(0, 100, 255) self.pen = QPen(pencolor, 1, QtCore.Qt.SolidLine) self.pen.setCosmetic(True) self.path = QPainterPath() self.path.addText(QtCore.QPointF(0, 0), QFont("Arial", 10 / self.sc), self.text) def contains_point(self, point): """ Text cannot be selected. Return maximal distance """ return float(0x7fffffff) def setSelected(self, *args): """ Override inherited function - with possibility to be called with multiple arguments """ def paint(self, painter, option, widget=None): """ Method for painting the arrow. """ demat = painter.deviceTransform() self.sc = demat.m11() # painter.setClipRect(self.boundingRect()) painter.setPen(self.pen) painter.setBrush(self.brush) painter.scale(1 / self.sc, 1 / self.sc) painter.translate(self.startp.x() * self.sc, self.startp.y() * self.sc) painter.drawPath(self.path) def shape(self): """ Reimplemented function to select outline only. @return: Returns the Outline only """ logger.debug("Hier sollte ich nicht sein") return super(RouteText, self).shape() def boundingRect(self): """ Required method for painting. Inherited by Painterpath @return: Gives the Bounding Box """ rect = self.path.boundingRect().getRect() newrect = QtCore.QRectF(self.startp.x() + rect[0] / self.sc, self.startp.y() + rect[1] / self.sc, rect[2] / self.sc, rect[3] / self.sc) return newrect
class Segment(QGraphicsItem): ''' # 新建Path QPath 可以通过从empty path或者另一个path新建, Once created, lines and curves can be added to the path using the lineTo(), arcTo(), cubicTo() and quadTo() functions. currentPosition() of the QPainterPath object is always the end position of the last subpath that was added (or the initial start point) # 开始新的subpath的两种方法: moveTo(): function implicitly starts a new subpath, and closes the previous one. closeSubpath():Another way of starting a new subpath is to call the closeSubpath() function which closes the current path by adding a line from the currentPosition() back to the path's start position. Note that the new path will have (0, 0) as its initial currentPosition(). # 一些便捷的方法: addEllipse(), addPath(), addRect(), addRegion() and addText(). The addPolygon() function adds an unclosed subpath. In fact, these functions are all collections of moveTo(), lineTo() and cubicTo() operations. # 连接到上一条Path: In addition, a path can be added to the current path using the connectPath() function. But note that this function will connect the last element of the current path to the first element of given one by adding a line. ''' def __init__(self, color, offset, parent): # offset接收一个偏移量,这是身子相对于头的偏移量 super(Segment, self).__init__(parent) self.color = color self.rect = QRectF(offset, -20, 30, 40) self.path = QPainterPath() self.path.addEllipse(self.rect) x = offset + 15 y = -20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y - 12), QPointF(x - 5, y)])) self.path.closeSubpath() # Closes the current subpath by drawing a line to the beginning of the subpath, # automatically starting a new path. # The current point of the new path is (0, 0). y = 20 self.path.addPolygon( QPolygonF( [QPointF(x, y), QPointF(x - 5, y + 12), QPointF(x - 5, y)])) self.path.closeSubpath() self.change = 1 self.angle = 0 self.timer = QTimer() self.timer.timeout.connect(self.timeout) self.timer.start(INTERVAL) def boundingRect(self): return self.path.boundingRect() def shape(self): return self.path def paint(self, painter, option, widget=None): painter.setPen(Qt.NoPen) painter.setBrush(QBrush(self.color)) global SCALE martix = SCALE if option.levelOfDetailFromTransform(martix) < 0.9: painter.drawEllipse(self.rect) else: painter.drawPath(self.path) def timeout(self): if not Running: # print("暂停身体生成") return matrix = self.transform() matrix.reset() self.setTransform(matrix) self.angle += self.change if self.angle > 3: self.change = -1 self.angle -= 1 # print("浪过去") elif self.angle < -3: self.change = 1 self.angle += 1 # print("浪回来") self.setRotation(self.angle)