def render_avatar_image(image: QImage, size: float): if image.isNull(): return None aspect_ratio = image.width() / image.height() if aspect_ratio > 1: width = size height = size / aspect_ratio else: width = size * aspect_ratio height = size x0 = (size - width) / 2 y0 = (size - height) / 2 path = QPainterPath() path.addEllipse(QRectF(x0, y0, width, height)) picture = QPicture() painter = QPainter(picture) painter.setRenderHint(QPainter.Antialiasing, True) pen = QPen(Qt.black, 5) pen.setStyle(Qt.SolidLine) painter.setPen(pen) painter.setClipPath(path) painter.drawImage( QRectF(x0, y0, width, height), image, ) painter.end() return picture
def paintEvent(self, event): super(CAvatar, self).paintEvent(event) # 画笔 painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.HighQualityAntialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) # 绘制 path = QPainterPath() diameter = min(self.width(), self.height()) if self.shape == self.Circle: radius = int(diameter / 2) elif self.shape == self.Rectangle: radius = 4 halfW = self.width() / 2 halfH = self.height() / 2 painter.translate(halfW, halfH) path.addRoundedRect( QRectF(-halfW, -halfH, diameter, diameter), radius, radius) painter.setClipPath(path) # 如果是动画效果 if self.rotateAnimation.state() == QPropertyAnimation.Running: painter.rotate(self._angle) # 旋转 painter.drawPixmap( QPointF(-self.pixmap.width() / 2, -self.pixmap.height() / 2), self.pixmap) else: painter.drawPixmap(-int(halfW), -int(halfH), self.pixmap) # 如果在加载 if self.loadingTimer.isActive(): diameter = 2 * self.pradius painter.setBrush( QColor(45, 140, 240, (1 - self.pradius / 10) * 255)) painter.setPen(Qt.NoPen) painter.drawRoundedRect( QRectF(-self.pradius, -self.pradius, diameter, diameter), self.pradius, self.pradius)
def __init__(self, antialiasing=True): super(Label, self).__init__(*args, **kwargs) self.Antialiasing = antialiasing self.setMaximumSize(50, 50) self.setMinimumSize(50, 50) self.radius = 25 self.target = QPixmap(self.size()) self.target.fill(Qt.transparent) p = QPixmap(self.image).scaled(50, 50, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) painter = QPainter(self.target) if self.Antialiasing: painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.HighQualityAntialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) path = QPainterPath() path.addRoundedRect(0, 0, self.width(), self.height(), self.radius, self.radius) painter.setClipPath(path) painter.drawPixmap(0, 0, p) self.setPixmap(self.target)
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 __init__(self, *args, antialiasing=True, **kwargs): super(Label, self).__init__(*args, **kwargs) self.Antialiasing = antialiasing self.setMaximumSize(200, 200) self.setMinimumSize(200, 200) self.radius = 100 #####################核心实现######################### self.target = QPixmap(self.size()) # 大小和控件一样 self.target.fill(Qt.transparent) # 填充背景为透明 p = QPixmap("head.jpg").scaled( # 加载图片并缩放和控件一样大 200, 200, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) painter = QPainter(self.target) if self.Antialiasing: # 抗锯齿 painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.HighQualityAntialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) # painter.setPen(# 测试圆圈 # QPen(Qt.red, 5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) path = QPainterPath() path.addRoundedRect(0, 0, self.width(), self.height(), self.radius, self.radius) #**** 切割为圆形 ****# painter.setClipPath(path) # painter.drawPath(path) # 测试圆圈 painter.drawPixmap(0, 0, p) self.setPixmap(self.target)
def set_rounded_pixmap(self): # Получаем минимальную высоту, которую может занимать Label size = self.picture_label.minimumSizeHint().height() radius = size // 2 color = QColor(*self.info[5]) # Создаём прозрачный QPixmap, на который будем накладывать иконку target = QPixmap(QSize(size, size)) target.fill(Qt.transparent) painter = QPainter() painter.begin(target) pixmap = QPixmap(QSize(size, size)) pixmap.fill(color) # Создаём объект, который будет хранить инструкции для рисования круга # В данном случае можно было обойтись без него, он используется для рисования # более сложных фигур, особенно когда нужно рисовать их несколько раз path = QPainterPath() path.addRoundedRect(0, 0, size, size, radius, radius) painter.setClipPath(path) # Накладываем содержимое объекта pixmap на target # В данном случае накладываем круг на прозрачное изображение painter.drawPixmap(0, 0, pixmap) painter.end() self.picture_label.setPixmap(target)
def setPixmap(self, path): if not os.path.exists(path): self._image = '' self._pixmap = None return self._image = path size = min(self.width(), self.height()) - self.padding # 需要边距的边框 radius = int(size / 2) image = QImage(size, size, QImage.Format_ARGB32_Premultiplied) image.fill(Qt.transparent) # 填充背景为透明 pixmap = QPixmap(path).scaled(size, size, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) # QPainter painter = QPainter() painter.begin(image) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) # QPainterPath path = QPainterPath() path.addRoundedRect(0, 0, size, size, radius, radius) # 切割圆 painter.setClipPath(path) painter.drawPixmap(0, 0, pixmap) painter.end() self._pixmap = QPixmap.fromImage(image) self.update()
def paintEvent(self, event): super(DeviceCard, self).paintEvent(event) painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHints(QPainter.SmoothPixmapTransform) path = QPainterPath() # 绘制图标 c = 0 r = 0 margin = 0 if not self.hover_progress or self.hover_progress < 20: c = self.choking r = self.radius_x else: c = self.choking * (1 - self.getNolinearProg( self.hover_progress, NolinearType.SlowFaster if self.hovering else NolinearType.SlowFaster)) r = self.radius_x if self.radius_zoom < 0 else self.radius_x + ( self.radius_zoom - self.radius_x) * self.hover_progress / 100 rect = QRectF(10, 10, 80 - c * 2, 80 - c * 2) path.addRoundedRect(rect, 4, 4) painter.save() painter.setClipPath(path, Qt.IntersectClip) painter.drawPixmap(rect.x(), rect.y(), rect.width(), rect.height(), self.model.icon) painter.restore() # 绘制编号 fm = QFontMetrics(self.title_font) line_height = fm.lineSpacing() painter.setPen(self.title_color) painter.setFont(self.title_font) painter.drawText(QPoint(94 - c * 2, 36), self.model.sn) fm = QFontMetrics(self.body_font) line_height = fm.lineSpacing() painter.setPen(self.body_color) painter.setFont(self.body_font) f_rect = fm.boundingRect(QRect(94 - c * 2, 30 + line_height, 0, 0), Qt.TextSingleLine, self.model.name) painter.drawText(f_rect, Qt.TextSingleLine, self.model.name) f_rect = fm.boundingRect(QRect(94 - c * 2, 46 + line_height, 0, 0), Qt.TextSingleLine, self.model.active) painter.drawText(f_rect, Qt.TextSingleLine, self.model.active) # 状态位置 self.tag.move(220 - self.tag.tag_width() - 10 - c, 10)
def PixmapToRound(label, icon): x0 = label.width() y0 = label.height() temp = QPixmap(x0, y0) temp.fill(Qt.transparent) painter = QPainter(temp) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) path = QPainterPath() path.addEllipse(0, 0, x0, y0) painter.setClipPath(path) painter.drawPixmap(0, 0, x0, y0, icon) painter.end() return temp
def getAverageColorFromPosition(x, y, emit): window = int(QApplication.desktop().winId()) r, d = _PICK_RADIUS, 1 + 2 * _PICK_RADIUS image = QApplication.primaryScreen().grabWindow(window, x - r, y - r, d, d).toImage() rect = image.rect() painter = QPainter(image) path = QPainterPath() path.addRoundedRect(0, 0, d, d, r, r) painter.setClipPath(path) # Clip so we don't include the marker pixels painter.end() emit(_getAverageColorFromImage(image))
def _createPointer(self): # 绘制一个小圆环 self._imagePointer = QImage(12, 12, QImage.Format_ARGB32) self._imagePointer.fill(Qt.transparent) painter = QPainter() painter.begin(self._imagePointer) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) painter.setPen(QPen(Qt.white, 2)) painter.setBrush(Qt.NoBrush) path = QPainterPath() path.addRoundedRect(0, 0, 12, 12, 6.0, 6.0) painter.setClipPath(path) painter.drawRoundedRect(0, 0, 12, 12, 6.0, 6.0) painter.end()
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 paintEvent(self, event): super(ScaleWindow, self).paintEvent(event) if self._image: painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) path = QPainterPath() radius = min(self.width(), self.height()) / 2 path.addRoundedRect(QRectF(self.rect()), radius, radius) painter.setClipPath(path) painter.drawImage(self.rect(), self._image) painter.setPen(QPen(QColor(0, 174, 255), 3)) hw = self.width() / 2 hh = self.height() / 2 painter.drawLines(QLineF(hw, 0, hw, self.height()), QLineF(0, hh, self.width(), hh)) painter.setPen(QPen(Qt.white, 3)) painter.drawRoundedRect(self.rect(), radius, radius)
def draw(self, p: QPainter): p.setRenderHint(QPainter.Antialiasing) crect = self.contentsRect() p.setClipPath(_rounded_rect_clip(self.rect(), self.MARGIN * 2)) p.fillRect(self.rect(), _gradient(self.height(), self.bg_dark, self.bg_light)) if self.model is None: return for attr in reversed(KireGaugeColors._fields): value = self.model.get_percent(attr) if value == 0: continue color = getattr(self.colors, attr) p.setClipPath(_rounded_rect_clip(crect, self.MARGIN)) p.fillRect(crect.x(), crect.y(), crect.width() * value, crect.height(), _gradient(crect.height(), color.lighter(), color))
def uiBatteryIconPaintEvent(evt, rectSize=24): """Draw the little coloured square on the focus peaking button.""" if self._batteryPresent and (self._batteryCharging or not self._batteryBlink): powerDownLevel = api.apiValues.get('powerOffWhenMainsLost') * self.uiPowerDownThreshold warningLevel = powerDownLevel + 0.15 x,y,w,h = ( 1, 1, self.uiBatteryIcon.width() - 2, self.uiBatteryIcon.height() - 1, ) p = QPainter(self.uiBatteryIcon) #Cut out the battery outline, so the battery fill level doesn't show by #outside the "nub". Nextly, this was taken care of by an opaque box #outside the battery nub in the SVG image, but this didn't work so well #when the button was pressed or when themes were changed. We can't fill #a polygon a percentage of the way very easily, and we can't just go in #and muck with the SVG to achieve this either like we would in browser. batteryOutline = QPainterPath() batteryOutline.addPolygon(QPolygonF([ QPoint(x+3,y), QPoint(x+3,y+2), #Left battery nub chunk. QPoint(x,y+2), QPoint(x,y+h), #Bottom QPoint(x+w,y+h), QPoint(x+w,y+2), QPoint(x+w-3,y+2), #Right battery nub chunk. QPoint(x+w-3,y), ])) batteryOutline.closeSubpath() #Top of battery nub. p.setClipPath(batteryOutline, Qt.IntersectClip) p.setPen(QPen(QColor('transparent'))) if self._batteryCharge > warningLevel or self._batteryCharging: p.setBrush(QBrush(QColor('#00b800'))) else: p.setBrush(QBrush(QColor('#f20000'))) p.drawRect( x, y + h * (1-self._batteryCharge), w, h * self._batteryCharge ) type(self.uiBatteryIcon).paintEvent(self.uiBatteryIcon, evt) #Invoke the superclass to paint the battery overlay image on our new rect.
def displayImg(self, data): # mutex.lock() img = QPixmap() img.loadFromData(data.content) img = img.scaled(50, 50, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) self.canvas = QPixmap(50, 50) self.canvas.fill(Qt.transparent) painter = QPainter(self.canvas) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.HighQualityAntialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) path = QPainterPath() path.addEllipse(0, 0, 50, 50) painter.setClipPath(path) painter.drawPixmap(0, 0, img) self.AvatarLB.setPixmap(self.canvas) self.userLB.setText(conf['nickname'])
def paintEvent(self, event): super().paintEvent(event) size, mid = _MARKER_SIZE, _MARKER_SIZE / 2 painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) # Clip path = QPainterPath() path.addRoundedRect(QRectF(self.rect()), mid, mid) painter.setClipPath(path) # Set slight transparent fill to enable click and drag if self._isPressed: painter.setBrush(QBrush(QColor(255, 255, 255, 1))) # Fill # Draw outline painter.setPen(QPen(QColor(0, 174, 255), 8)) painter.drawRoundedRect(self.rect(), mid, mid)
def paintEvent(self, event): """重绘界面""" painter = QPainter(self) # 绘制背景颜色 painter.setBrush(self.backgroundColor) # 边框 painter.setPen( QPen(self.borderColor, self.borderWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) # 绘制区域 path = QPainterPath() path.addRoundedRect(0, 0, self.width(), self.height(), self.borderRadius, self.borderRadius) painter.setClipPath(path) painter.drawPath(path) # 绘制文字 font = self.font() or QFont() painter.setFont(font) painter.setPen(self.textColor) painter.drawText(self.rect(), Qt.AlignCenter, self.text())
def setPixmap(self, path: str) -> None: self._image = path size = min(self.width(), self.height()) - self.padding # 需要边距的边框 self._radius = int(size / 2) self._pixmap = QPixmap(size, size) self._pixmap.fill(Qt.transparent) # 填充背景为透明 tmp = QPixmap(path).scaled(size, size, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) # QPainter painter = QPainter() painter.begin(self._pixmap) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) # QPainterPath path = QPainterPath() path.addRoundedRect(0, 0, size, size, self._radius, self._radius) # 切割圆 painter.setClipPath(path) painter.drawPixmap(0, 0, tmp) painter.end() del tmp
def pixmap(self, mode=QIcon.Normal, state=QIcon.Off): pixmap = self.icon().pixmap(self.iconSize(), mode, state) if pixmap.isNull(): return pixmap size = max(pixmap.width(), pixmap.height()) offset_x = (size - pixmap.width()) / 2 offset_y = (size - pixmap.height()) / 2 new_pixmap = QPixmap(size, size) new_pixmap.fill(Qt.transparent) path = QPainterPath() path.addRoundedRect(0, 0, size, size, 3.7, 3.7) painter = QPainter(new_pixmap) painter.setRenderHint(QPainter.Antialiasing, True) painter.setCompositionMode(QPainter.CompositionMode_SourceOver) painter.setClipPath(path) painter.drawPixmap(offset_x, offset_y, pixmap) painter.end() return new_pixmap
def paintEvent(self, event): # Initializing QPainter qp = QPainter() qp.begin(self) qp.setRenderHint(QPainter.Antialiasing) sidebar_rect = self.geometry() # Gradient gradient = QLinearGradient(0, 0, sidebar_rect.width(), 0) gradient.setColorAt(0.0, self.color_gradient_left) gradient.setColorAt(1.0, self.color_gradient_right) qp.setBrush(QBrush(gradient)) # qp.setPen(Qt.white) qp.drawRect(0, 0, sidebar_rect.width(), sidebar_rect.height()) # Glass highlight qp.setBrush(QBrush(Qt.white)) qp.setPen(QPen(QBrush(Qt.white), 0.01)) qp.setOpacity(0.1) qppath = QPainterPath() qppath.moveTo(sidebar_rect.width() * 0.2, 0) qppath.quadTo(sidebar_rect.width() * 0.3, sidebar_rect.height() * 0.5, sidebar_rect.width() * 0.2, sidebar_rect.height() - 1) qppath.lineTo(0, sidebar_rect.height()) qppath.lineTo(0, 0) qp.setClipPath(qppath) qp.drawRect(1, 1, sidebar_rect.width() - 1, sidebar.height() - 1) # Left border highlight qp.setOpacity(1.0) gradient = QLinearGradient(0, 0, 2, 0) gradient.setColorAt(0.0, QColor(255, 255, 255, 80)) gradient.setColorAt(1.0, QColor(0, 0, 0, 0)) qp.setBrush(QBrush(gradient)) # qp.setPen(Qt.transparent) qp.drawRect(0, 0, 8, sidebar_rect.height()) qp.end()
def paintEvent(self, event): super(CColorControl, self).paintEvent(event) painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) painter.setPen(Qt.NoPen) # 变换圆心 painter.translate(self.rect().center()) # 画背景方格图 painter.save() # 保证方格在前景圆内部 diameter = min(self.width(), self.height()) - 8 radius = diameter / 2 path = QPainterPath() path.addRoundedRect(-radius, -radius, diameter, diameter, radius, radius) painter.setClipPath(path) pixSize = 5 for x in range(int(self.width() / pixSize)): for y in range(int(self.height() / pixSize)): _x, _y = x * pixSize, y * pixSize painter.fillRect(_x - radius, _y - radius, pixSize, pixSize, Qt.white if x % 2 != y % 2 else Qt.darkGray) painter.restore() # 画前景颜色 diameter = min(self.width(), self.height()) - 4 radius = diameter / 2 path = QPainterPath() path.addRoundedRect(-radius, -radius, diameter, diameter, radius, radius) painter.setClipPath(path) painter.setBrush(self._color) painter.drawRoundedRect(-radius, -radius, diameter, diameter, radius, radius)
def paintEvent(self, event): """重绘界面""" option = QStyleOptionButton() self.initStyleOption(option) hover = option.state == (option.state | QStyle.State_MouseOver) painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.HighQualityAntialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) if not self.isFlat(): # 绘制背景颜色 painter.setBrush( self.backgroundColorHover if hover else self.backgroundColor) # 边框 painter.setPen( QPen( # 如果鼠标按下则边框颜色为背景色(边框效应) self.backgroundColor if self.isDown() else (self.borderColorHover if hover else self.borderColor), # 鼠标按下则边框宽度 + 5(边框效应) self.borderWidth + 5 if self.isDown() else self.borderWidth, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) # 绘制区域 path = QPainterPath() path.addRoundedRect(0, 0, self.width(), self.height(), self.borderRadius, self.borderRadius) painter.setClipPath(path) painter.drawPath(path) # 绘制文字 font = self.font() or QFont() font.setUnderline(self.isFlat() and hover) # 如果是设置的Flat并且鼠标悬停则加上下划线 painter.setFont(font) painter.setPen(self.textColorHover if hover else self.textColor) painter.drawText(self.rect(), Qt.AlignCenter, self.text())
def __init__(self, path, size, parent=None, **kwargs): super(RoundedImg, self).__init__(parent=parent) self.setMaximumSize(size, size) self.setMinimumSize(size, size) self.radius = int(size/2) self.target = QPixmap(self.size()) self.target.fill(Qt.transparent) pic = QPixmap(path).scaled(size, size, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) painter = QPainter(self.target) painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.HighQualityAntialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) path_ = QPainterPath() path_.addRoundedRect(0, 0, self.width(), self.height(), self.radius, self.radius) painter.setClipPath(path_) painter.drawPixmap(0, 0, pic) self.setPixmap(self.target)
def initUI(self): #####################核心实现######################### self.target = QPixmap(self.size()) # 大小和控件一样 self.target.fill(Qt.transparent) # 填充背景为透明 # 加载图片并缩放和控件一样大 p = QPixmap("head.jpg").scaled(200, 200, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation) painter = QPainter(self.target) if self.Antialiasing: # 抗锯齿 painter.setRenderHint(QPainter.Antialiasing, True) painter.setRenderHint(QPainter.HighQualityAntialiasing, True) painter.setRenderHint(QPainter.SmoothPixmapTransform, True) path = QPainterPath() path.addRoundedRect(0, 0, self.width(), self.height(), self.radius, self.radius) # **** 切割为圆形 ****# painter.setClipPath(path) painter.drawPixmap(0, 0, p) self.setPixmap(self.target)
def paintEvent(self, event): p = QPainter() p.begin(self) self._normalMap.render(p, event.rect()) p.setPen(Qt.black) p.drawText(self.rect(), Qt.AlignBottom | Qt.TextWordWrap, "Map data CCBYSA 2009 OpenStreetMap.org contributors") p.end() if self.zoomed: dim = min(self.width(), self.height()) magnifierSize = min(MAX_MAGNIFIER, dim * 2 / 3) radius = magnifierSize / 2 ring = radius - 15 box = QSize(magnifierSize, magnifierSize) # reupdate our mask if self.maskPixmap.size() != box: self.maskPixmap = QPixmap(box) self.maskPixmap.fill(Qt.transparent) g = QRadialGradient() g.setCenter(radius, radius) g.setFocalPoint(radius, radius) g.setRadius(radius) g.setColorAt(1.0, QColor(255, 255, 255, 0)) g.setColorAt(0.5, QColor(128, 128, 128, 255)) mask = QPainter(self.maskPixmap) mask.setRenderHint(QPainter.Antialiasing) mask.setCompositionMode(QPainter.CompositionMode_Source) mask.setBrush(g) mask.setPen(Qt.NoPen) mask.drawRect(self.maskPixmap.rect()) mask.setBrush(QColor(Qt.transparent)) mask.drawEllipse(g.center(), ring, ring) mask.end() center = self.dragPos - QPoint(0, radius) center += QPoint(0, radius / 2) corner = center - QPoint(radius, radius) xy = center * 2 - QPoint(radius, radius) # only set the dimension to the magnified portion if self.zoomPixmap.size() != box: self.zoomPixmap = QPixmap(box) self.zoomPixmap.fill(Qt.lightGray) if True: p = QPainter(self.zoomPixmap) p.translate(-xy) self._largeMap.render(p, QRect(xy, box)) p.end() clipPath = QPainterPath() clipPath.addEllipse(QPointF(center), ring, ring) p = QPainter(self) p.setRenderHint(QPainter.Antialiasing) p.setClipPath(clipPath) p.drawPixmap(corner, self.zoomPixmap) p.setClipping(False) p.drawPixmap(corner, self.maskPixmap) p.setPen(Qt.gray) p.drawPath(clipPath) if self.invert: p = QPainter(self) p.setCompositionMode(QPainter.CompositionMode_Difference) p.fillRect(event.rect(), Qt.white) p.end()
def paintEvent(self, event): if self.minimum() == self.maximum() == 0: return # 正弦曲线公式 y = A * sin(ωx + φ) + k # 当前值所占百分比 percent = 1 - (self.value() - self.minimum()) / \ (self.maximum() - self.minimum()) # w表示周期,6为人为定义 w = 6 * self.waterDensity * math.pi / self.width() # A振幅 高度百分比,1/26为人为定义 A = self.height() * self.waterHeight * 1 / 26 # k 高度百分比 k = self.height() * percent # 波浪1 waterPath1 = QPainterPath() waterPath1.moveTo(0, self.height()) # 起点在左下角 # 波浪2 waterPath2 = QPainterPath() waterPath2.moveTo(0, self.height()) # 起点在左下角 # 偏移 self._offset += 0.6 if self._offset > self.width() / 2: self._offset = 0 for i in range(self.width() + 1): # 从x轴开始计算y轴点 y = A * math.sin(w * i + self._offset) + k waterPath1.lineTo(i, y) # 相对第一条需要进行错位 y = A * math.sin(w * i + self._offset + self.width() / 2 * A) + k waterPath2.lineTo(i, y) # 封闭两条波浪,形成一个 U形 上面加波浪的封闭区间 waterPath1.lineTo(self.width(), self.height()) waterPath1.lineTo(0, self.height()) waterPath2.lineTo(self.width(), self.height()) waterPath2.lineTo(0, self.height()) # 整体形状(矩形或者圆形) bgPath = QPainterPath() if self.styleType: bgPath.addRect(QRectF(self.rect())) else: radius = min(self.width(), self.height()) bgPath.addRoundedRect(QRectF(self.rect()), radius, radius) # 开始画路径 painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing, True) # 设置没有画笔 painter.setPen(Qt.NoPen) if not self.styleType: # 圆形 painter.setClipPath(bgPath) # 先整体绘制背景,然后再在背景上方绘制两条波浪 painter.save() painter.setBrush(self.backgroundColor) painter.drawPath(bgPath) painter.restore() # 波浪1 painter.save() painter.setBrush(self.waterColor1) painter.drawPath(waterPath1) painter.restore() # 波浪2 painter.save() painter.setBrush(self.waterColor2) painter.drawPath(waterPath2) painter.restore() # 绘制文字 if not self.isTextVisible(): return painter.setPen(self.textColor) font = self.font() or QFont() font.setPixelSize(int(min(self.width(), self.height()) / 2)) painter.setFont(font) painter.drawText(self.rect(), Qt.AlignCenter, '%d%%' % (self.value() / self.maximum() * 100))
def paintEvent(self, event): qp = QPainter() qp.begin(self) qp.setPen(self.textColor) qp.setFont(self.font) qp.setRenderHint(QPainter.Antialiasing) w = 0 # Draw time scale = self.getScale() while w <= self.width(): qp.drawText(w - 50, 0, 100, 100, Qt.AlignHCenter, self.get_time_string(w * scale)) w += 100 # Draw down line qp.setPen(QPen(Qt.darkCyan, 5, Qt.SolidLine)) qp.drawLine(0, 40, self.width(), 40) # Draw dash lines point = 0 qp.setPen(QPen(self.textColor)) qp.drawLine(0, 40, self.width(), 40) while point <= self.width(): if point % 30 != 0: qp.drawLine(3 * point, 40, 3 * point, 30) else: qp.drawLine(3 * point, 40, 3 * point, 20) point += 10 if self.pos is not None and self.is_in: qp.drawLine(self.pos.x(), 0, self.pos.x(), 40) if self.pointerPos is not None: line = QLine( QPoint(self.pointerTimePos / self.getScale(), 40), QPoint(self.pointerTimePos / self.getScale(), self.height())) poly = QPolygon([ QPoint(self.pointerTimePos / self.getScale() - 10, 20), QPoint(self.pointerTimePos / self.getScale() + 10, 20), QPoint(self.pointerTimePos / self.getScale(), 40) ]) else: line = QLine(QPoint(0, 0), QPoint(0, self.height())) poly = QPolygon([QPoint(-10, 20), QPoint(10, 20), QPoint(0, 40)]) # Draw samples t = 0 for sample in self.videoSamples: # Clear clip path path = QPainterPath() path.addRoundedRect( QRectF(t / scale, 50, sample.duration / scale, 200), 10, 10) qp.setClipPath(path) # Draw sample path = QPainterPath() qp.setPen(sample.color) path.addRoundedRect( QRectF(t / scale, 50, sample.duration / scale, 50), 10, 10) sample.startPos = t / scale sample.endPos = t / scale + sample.duration / scale qp.fillPath(path, sample.color) qp.drawPath(path) # Draw preview pictures if sample.picture is not None: if sample.picture.size().width() < sample.duration / scale: path = QPainterPath() path.addRoundedRect( QRectF(t / scale, 52.5, sample.picture.size().width(), 45), 10, 10) qp.setClipPath(path) qp.drawPixmap( QRect(t / scale, 52.5, sample.picture.size().width(), 45), sample.picture) else: path = QPainterPath() path.addRoundedRect( QRectF(t / scale, 52.5, sample.duration / scale, 45), 10, 10) qp.setClipPath(path) pic = sample.picture.copy(0, 0, sample.duration / scale, 45) qp.drawPixmap( QRect(t / scale, 52.5, sample.duration / scale, 45), pic) t += sample.duration # Clear clip path path = QPainterPath() path.addRect(self.rect().x(), self.rect().y(), self.rect().width(), self.rect().height()) qp.setClipPath(path) # Draw pointer qp.setPen(Qt.darkCyan) qp.setBrush(QBrush(Qt.darkCyan)) qp.drawPolygon(poly) qp.drawLine(line) qp.end()
def drawImageFunction(self, painter: QtGui.QPainter): painter.setClipPath(self.path) painter.drawImage(QtCore.QPoint(), self.image)
def paintEvent(self, _): """ 重写绘制事件,参考 qfusionstyle.cpp 中的 CE_ProgressBarContents 绘制方法 """ option = QStyleOptionProgressBar() self.initStyleOption(option) painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.translate(0.5, 0.5) vertical = option.orientation == Qt.Vertical # 是否垂直 inverted = option.invertedAppearance # 是否反转 # 是否显示动画 indeterminate = (option.minimum == option.maximum) or ( option.minimum < option.progress < option.maximum) rect = option.rect if vertical: rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()) # 翻转宽度和高度 m = QTransform.fromTranslate(rect.height(), 0) m.rotate(90.0) painter.setTransform(m, True) maxWidth = rect.width() progress = max(option.progress, option.minimum) totalSteps = max(1, option.maximum - option.minimum) progressSteps = progress - option.minimum progressBarWidth = int(progressSteps * maxWidth / totalSteps) width = progressBarWidth # 已进行的进度宽度 radius = max(1, (min(width, self.width() if vertical else self.height()) // 4) if self._radius is None else self._radius) reverse = (not vertical and option.direction == Qt.RightToLeft) or vertical if inverted: reverse = not reverse # 绘制范围 path = QPainterPath() if not reverse: progressBar = QRectF(rect.left(), rect.top(), width, rect.height()) else: progressBar = QRectF(rect.right() - width, rect.top(), width, rect.height()) # 切割范围 path.addRoundedRect(progressBar, radius, radius) painter.setClipPath(path) # 绘制背景颜色 painter.setPen(Qt.NoPen) painter.setBrush(self._color) painter.drawRoundedRect(progressBar, radius, radius) if not indeterminate: if self._animation: self._animation.stop() self._animation = None else: # 叠加颜色覆盖后出现类似线条间隔的效果 color = self._color.lighter(320) color.setAlpha(80) painter.setPen(QPen(color, self._lineWidth)) if self._animation: step = int(self._animation.animationStep() % self._lineWidth) else: step = 0 self._animation = QProgressStyleAnimation(self._fps, self) self._animation.start() # 动画斜线绘制 startX = int(progressBar.left() - rect.height() - self._lineWidth) endX = int(rect.right() + self._lineWidth) if (not inverted and not vertical) or (inverted and vertical): lines = [ QLineF(x + step, progressBar.bottom(), x + rect.height() + step, progressBar.top()) for x in range(startX, endX, self._lineWidth) ] else: lines = [ QLineF(x - step, progressBar.bottom(), x + rect.height() - step, progressBar.top()) for x in range(startX, endX, self._lineWidth) ] painter.drawLines(lines)