1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| from PySide6.QtCore import QPointF from PySide6.QtGui import Qt, QFont, QColor, QPainterPath, QPolygonF, QBrush, QPixmap from PySide6.QtWidgets import QGraphicsDropShadowEffect, QGraphicsPolygonItem from PySide6.QtWidgets import QGraphicsRectItem, QGraphicsSimpleTextItem, QGraphicsPixmapItem
class TextInfo: def __init__(self, params): self.content = params.get('content', '默认文字') self.size = params.get('size', 40) self.gap = self.size // 10 self.ziti = params.get('ziti', '黑体') self.border = params.get('border', '圆角') self.align = params.get('align', '居中') self.bold = params.get('bold', True) self.italic = params.get('italic', True) self.triangle = params.get('triangle', False) self.color = params.get('color', '#000000') self.shadow = params.get('shadow', '#ffffff') self.background = params.get('background', '#00000000') self.image = params.get('image', None)
class TextRect(QGraphicsRectItem): def __init__(self, text, text_info): super().__init__() self.setPen(Qt.NoPen) self.text_item = QGraphicsSimpleTextItem(text) self.text_item.setBrush(QColor(text_info.color)) shadow_effect = QGraphicsDropShadowEffect() shadow_effect.setBlurRadius(8) shadow_effect.setColor(QColor(text_info.shadow)) shadow_effect.setOffset(3, 3) self.text_item.setGraphicsEffect(shadow_effect) font = QFont(text_info.ziti, text_info.size) font.setBold(text_info.bold) font.setItalic(text_info.italic) self.text_item.setFont(font) self.text_item.setParentItem(self)
def offset(self, x, y): self.text_item.setPos(x, y)
def width(self): return self.text_item.boundingRect().width()
def height(self): return self.text_item.boundingRect().height()
class PatchText(QGraphicsRectItem): def __init__(self, params): super().__init__() self.setPen(Qt.NoPen) self.text_info = TextInfo(params) self.setBrush(QColor(self.text_info.background)) self.text_line_list = [] w, h = 0, self.text_info.gap * 2 for line in self.text_info.content.split('\n'): if not line: line = ' ' * 4 text_line = TextRect(line, self.text_info) w = max(w, text_line.width() + self.text_info.gap * 8) h += text_line.height() + self.text_info.gap self.text_line_list.append(text_line) text_line.setParentItem(self) x, y = self.text_info.gap * 4, self.text_info.gap * 2 for text_line in self.text_line_list: if self.text_info.align == '居中': x = (w - text_line.width()) // 2 if self.text_info.align == '右对齐': x = w - text_line.width() - self.text_info.gap * 4 text_line.setRect(0, y, w, text_line.height()) text_line.offset(x, y) y += text_line.height() + self.text_info.gap h = h + self.text_info.gap * 2 self.setRect(0, 0, w, h) if self.text_info.triangle: side = self.text_info.gap * 10 triangle = QGraphicsPolygonItem() triangle.setPen(Qt.NoPen) points = QPolygonF([ QPointF(w - side * 2, h), QPointF(w - side, h), QPointF(w - side * 1.5, h + side * 0.5) ]) triangle.setPolygon(points) triangle.setBrush(QBrush(QColor(self.text_info.background))) triangle.setParentItem(self) if self.text_info.image: pixmap = QGraphicsPixmapItem() pixmap.setZValue(-1) pixmap.setPixmap(QPixmap(self.text_info.image)) pixmap.setParentItem(self) x, y = (w - pixmap.boundingRect().width()) // 2, (h - pixmap.boundingRect().height()) // 2 pixmap.setPos(x, y) xx = x * -1 if x < 0 else 0 yy = y * -1 if y < 0 else 0 self.setRect(0, 0, w + xx * 2, h + yy * 2) self.setPos(xx, yy)
def paint(self, painter, option, widget=None): if self.text_info.border != '圆角': super().paint(painter, option, widget) return radius = self.text_info.gap * 4 painter.save() path = QPainterPath() path.addRoundedRect(self.rect(), radius, radius) if self.brush().style() != Qt.NoBrush: painter.fillPath(path, self.brush()) if self.pen().style() != Qt.NoPen: painter.setPen(self.pen()) painter.drawPath(path) painter.restore()
|