实现圆形图片我们有两种方式:
第一种:使用qss样式表的border-radius来实现控件的圆形效果,但这种方式会出现边界锯齿模糊的问题
第二种:重写控件 paintEvent 事件来重新绘制
这里我们讨论的是第二种方式,下面是控件实现的代码:
class CircleImage(QWidget):'''绘制圆形图片'''def __init__(self, parent=None):super(CircleImage, self).__init__(parent)self.resize(100, 100)self.circle_image = Nonedef set_image(self, image):'''设置绘制的图片'''self.circle_image = imageself.update()def paintEvent(self, event):'''重写绘制事件'''super(CircleImage, self).paintEvent(event)painter = QPainter(self)painter.setRenderHint(QPainter.Antialiasing, True) # 设置抗锯齿pen = Qt.NoPenpainter.setPen(pen) # 设置取消描边边框brush = QBrush(self.circle_image) painter.setBrush(brush)# 设置绘制内容painter.drawRoundedRect(self.rect(), self.width() / 2, self.height() / 2)
这里有两个概念需要解释一下:
下面是测试单元程序代码:
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_())
这里需要介绍一下的是对图片缩放时设置的参数
效果如下
如果给窗口设置透明背景就可以做到一些特殊效果
# 去除背景self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)self.setAttribute(Qt.WA_TranslucentBackground)
整个窗口只显示出这个圆形图片
当然我们也可以添加一个边框进去:
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)
这是因为我们添加了边框之后,绘制的内容就包含了边框的宽度:水平方向包含左右两边,垂直方向包含上下两边
得到效果如下:
如果把绘制的图片去掉就可以实现出空心圆环的效果:
brush = QBrush(Qt.NoBrush)# 移除绘制的内容