PyQt自定义控件之实现圆形图片

实现圆形图片我们有两种方式:

第一种:使用 qss样式表border-radius 来实现控件的圆形效果,但这种方式会出现边界锯齿模糊的问题

第二种:重写控件 paintEvent 事件来重新绘制

这里我们讨论的是第二种方式,下面是控件实现的代码:

class CircleImage(QWidget):
    '''绘制圆形图片'''

    def __init__(self, parent=None):
        super(CircleImage, self).__init__(parent)
        self.resize(100, 100)
        self.circle_image = None

    def set_image(self, image):
        '''设置绘制的图片'''
        self.circle_image = image
        self.update()

    def paintEvent(self, event):
        '''重写绘制事件'''
        super(CircleImage, self).paintEvent(event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)  # 设置抗锯齿
        pen = Qt.NoPen
        painter.setPen(pen)                            		# 设置取消描边边框
        brush = QBrush(self.circle_image)                   
        painter.setBrush(brush)								# 设置绘制内容
        painter.drawRoundedRect(self.rect(), self.width() / 2, self.height() / 2)

这里有两个概念需要解释一下:

画笔(QPen) 用于设置绘制内容的描边边框,这里设置为Qt.NoPen表示取消描边边框
刷子(QBrush) 用于设置绘制的内容,可以为图片或者颜色

下面是测试单元程序代码:

if __name__ == '__main__':
    # 控件测试程序
    app = QApplication(sys.argv)

    widget = CircleImage()
    image = QPixmap('test.png')
    widget.set_image(image.scaled(widget.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
    widget.show()

    sys.exit(app.exec_())

这里需要介绍一下的是对图片缩放时设置的参数

Qt.KeepAspectRatio 用于设置缩放图片时保持比例
Qt.SmoothTransformation 用于设置图片转换过程中避免失真

效果如下
PyQt自定义控件之实现圆形图片_第1张图片
如果给窗口设置透明背景就可以做到一些特殊效果

# 去除背景
self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)

整个窗口只显示出这个圆形图片
PyQt自定义控件之实现圆形图片_第2张图片


当然我们也可以添加一个边框进去:

    def paintEvent(self, event):
        '''重写绘制事件'''
        super(CircleImage, self).paintEvent(event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing, True)  
        pen = QPen(QColor('#ff0000'))                       # 设置边框颜色
        pen.setWidth(2)                                     # 设置边框宽度
        painter.setPen(pen)                                 # 添加描边边框
        brush = QBrush(self.circle_image)                   
        painter.setBrush(brush)
        rect = QRect(2, 2, self.width() - 4, self.height() - 4)
        painter.drawRoundedRect(rect, self.width() / 2, self.height() / 2)

这里我们有留意到绘制的时候坐标位置进行了调整

rect = QRect(2, 2, self.width() - 4, self.height() - 4)

这是因为我们添加了边框之后,绘制的内容就包含了边框的宽度:水平方向包含左右两边,垂直方向包含上下两边

得到效果如下:

PyQt自定义控件之实现圆形图片_第3张图片


如果把绘制的图片去掉就可以实现出空心圆环的效果:

brush = QBrush(Qt.NoBrush)	# 移除绘制的内容

PyQt自定义控件之实现圆形图片_第4张图片

你可能感兴趣的:(PyQt自定义控件)