Qt中圆形头像

Catalogue   

业务需求中经常需要头像是圆形的,一些数字底部有圆形背景,于是将其整理出来,以便以后方便的使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class CircleThumbWiget(QWidget):
def __init__(self, parent=None, radius=40):
"""
radius 表示这个圆形控件的大小
"""
super(CircleThumbWiget, self).__init__(parent)
self.imageLabel = QLabel(self)
self.imageLabel.setScaledContents(True)
self.imageLabel.setGeometry(0, 0, radius, radius)
defaultPixmap = QPixmap("resources/icon/default_user.png")
self.imageLabel.setPixmap(defaultPixmap)
# 这里使用一张周边透明的圆形的png图片
img = QImage("resources/icon/default_user_mask.png")
bg = QPixmap.fromImage(img.scaled(QSize(radius, radius), Qt.IgnoreAspectRatio))
palette = self.palette()
palette.setBrush(QPalette.Background, QBrush(bg))
self.setPalette(palette)
self.setMask(bg.mask())

def setPixmap(self, pixmap):
self.imageLabel.setPixmap(pixmap)

平滑的圆形头像

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
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QBrush, QImage, QPainter, QPixmap, QWindow
from PyQt5.QtWidgets import QLabel, QVBoxLayout, QWidget


def mask_image(imgdata, imgtype='png', size=64):
"""Return a ``QPixmap`` from *imgdata* masked with a smooth circle.

*imgdata* are the raw image bytes, *imgtype* denotes the image type.

The returned image will have a size of *size* × *size* pixels.

"""
# Load image and convert to 32-bit ARGB (adds an alpha channel):
image = QImage.fromData(imgdata, imgtype)
image.convertToFormat(QImage.Format_ARGB32)

# Crop image to a square:
imgsize = min(image.width(), image.height())
rect = QRect(
(image.width() - imgsize) / 2,
(image.height() - imgsize) / 2,
imgsize,
imgsize,
)
image = image.copy(rect)

# Create the output image with the same dimensions and an alpha channel
# and make it completely transparent:
out_img = QImage(imgsize, imgsize, QImage.Format_ARGB32)
out_img.fill(Qt.transparent)

# Create a texture brush and paint a circle with the original image onto
# the output image:
brush = QBrush(image) # Create texture brush
painter = QPainter(out_img) # Paint the output image
painter.setBrush(brush) # Use the image texture brush
painter.setPen(Qt.NoPen) # Don't draw an outline
painter.setRenderHint(QPainter.Antialiasing, True) # Use AA
painter.drawEllipse(0, 0, imgsize, imgsize) # Actually draw the circle
painter.end() # We are done (segfault if you forget this)

# Convert the image to a pixmap and rescale it. Take pixel ratio into
# account to get a sharp image on retina displays:
pr = QWindow().devicePixelRatio()
pm = QPixmap.fromImage(out_img)
pm.setDevicePixelRatio(pr)
size *= pr
pm = pm.scaled(size, size, Qt.KeepAspectRatio, Qt.SmoothTransformation)

return pm


class Window(QWidget):
"""Simple window that shows our masked image and text label."""

def __init__(self):
super().__init__()

imgpath = "U:/xxx/logo.png"
imgdata = open(imgpath, 'rb').read()
ext = imgpath.split(".")[-1]
pixmap = mask_image(imgdata, ext)
ilabel = QLabel()
ilabel.setScaledContents(True)
ilabel.setFixedWidth(26)
ilabel.setFixedHeight(26)
ilabel.setPixmap(pixmap)

layout = QVBoxLayout()
layout.addWidget(ilabel, 0, Qt.AlignCenter)
self.setLayout(layout)


if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication

app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())

参考