实现圆形图片的方法有很多,比如用遮罩(mask), 裁切等等。这里比较几种实现方式,选出个人认为最优的方案。
https://github.com/PyQt5/PyQt/blob/master/QLabel/CircleImage.py
# 采用 mask 方式
具体参考 【Qt】QLabel 实现的圆形图像 - 米罗西 - 博客园
# 画圆形遮盖(适合纯色背景)
原理是在原图片上画一个 4 角有颜色,中间圆形镂空的图片。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2017年8月25日
@author: Irony."[讽刺]
@site: https://pyqt5.com, https://github.com/892768447
@email: 892768447@qq.com
@description:
'''
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter, QPainterPath
from PyQt5.QtWidgets import QLabel, QWidget, QHBoxLayout
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
class Label(QLabel):
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.image = QPixmap("head.jpg").scaled(
200, 200, Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)
painter = QPainter(self.image)
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)
path.addRect(0,0,self.width(),self.height())
painter.setPen(Qt.NoPen)
painter.setBrush(Qt.green)
painter.drawPath(path)
self.setPixmap(self.image)
class Window(QWidget):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
layout = QHBoxLayout(self)
layout.addWidget(Label(self))
layout.addWidget(Label(self, antialiasing=False))
self.setStyleSheet("background: black;")
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
# 使用 QPainter 的 setCompositionMode
//result_avatar_size 是我们最后生成的图片的长宽,可以是QSize(200, 200)的正圆
destination_image = QImage(result_avatar_size, QImage::Format_ARGB32_Premultiplied);
//在黑色的正方形中间画一个透明的圆,作为头像遮罩
QPainter painter(&destination_image);
painter.setRenderHint(QPainter::Antialiasing);
//全涂黑
painter.fillRect(destination_image.rect(), QBrush(Qt::black, Qt::SolidPattern));
painter.setCompositionMode(QPainter::CompositionMode_SourceOut);
painter.setPen(Qt::NoPen);
painter.setBrush(QBrush(Qt::transparent, Qt::SolidPattern));
//画透明区域
painter.drawEllipse(destination_image.rect());
# 使用 QPainter 的切割方法(推荐)
利用 QPainter.setClipPath
方法切割一个圆形的 QPainterPath
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Created on 2017年8月25日
@author: Irony."[讽刺]
@site: https://pyqt5.com, https://github.com/892768447
@email: 892768447@qq.com
@file:
@description:
'''
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter, QPainterPath, QPen
from PyQt5.QtWidgets import QLabel, QWidget, QHBoxLayout
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2017 Irony.\"[讽刺]"
__Version__ = "Version 1.0"
class Label(QLabel):
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.black, 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)
#####################核心实现#########################
class Window(QWidget):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
layout = QHBoxLayout(self)
layout.addWidget(Label(self))
layout.addWidget(Label(self, antialiasing=False))
self.setStyleSheet("background: black;")
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 PyQt!