Python 向圆形标签图像添加边框

Python 向圆形标签图像添加边框,python,pyqt,pyqt5,Python,Pyqt,Pyqt5,我正在尝试创建一个带有边框的圆形标签,里面包含一个图像。到目前为止,我尝试设置样式表,将圆形图像QLabel与彩色背景重叠在一个更大的圆形QLabel上,并更改其大小策略,但无法获得非平庸的结果: 带有父背景标签(标记为FIX 2): 已设置样式表(标记为FIX 1): 这是MRE。在本例中,我在同一目录中使用蓝色背景: “steel_blue.png” 如果您只想在圆形图像周围绘制边框,那么使用叠加小部件肯定不是最明智的选择 您应该做的是直接创建包含边框的QPixmap 这是您的课程的修

我正在尝试创建一个带有边框的圆形标签,里面包含一个图像。到目前为止,我尝试设置样式表,将圆形图像QLabel与彩色背景重叠在一个更大的圆形QLabel上,并更改其大小策略,但无法获得非平庸的结果:

带有父背景标签(标记为FIX 2):

已设置样式表(标记为FIX 1):

这是MRE。在本例中,我在同一目录中使用蓝色背景:

“steel_blue.png”


如果您只想在圆形图像周围绘制边框,那么使用叠加小部件肯定不是最明智的选择

您应该做的是直接创建包含边框的QPixmap

这是您的课程的修订版和清理版:

class RoundLabelImage(qtw.QLabel):
    def __init__(self, path="", urlpath="", size=50, border_width=0, border_color=None, antialiasing=True):
        super().__init__()
        self.setFixedSize(size, size)

        if path != "":
            source = QPixmap(path)
        elif urlpath != "":
            # you really shouldn't rely on functions that are possibly blocking...
            data = urllib.request.urlopen(urlpath).read()
            source = QPixmap()
            source.loadFromData(data)

        pixmap_size = size - border_width * 2
        p = source.scaled(
            pixmap_size, pixmap_size, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)

        self.target = QPixmap(self.size())
        self.target.fill(QtCore.Qt.transparent)

        painter = QPainter(self.target)
        if antialiasing:
            painter.setRenderHint(QPainter.Antialiasing, True)
            painter.setRenderHint(QPainter.HighQualityAntialiasing, True)
            painter.setRenderHint(QPainter.SmoothPixmapTransform, True)

        rect = QtCore.QRectF(self.rect())
        if border_width:
            painter.setPen(QtCore.Qt.NoPen)
            painter.setBrush(QtGui.QColor(border_color))
            painter.drawEllipse(rect)
            rect.adjust(border_width, border_width, -border_width, -border_width)

        painter_path = QPainterPath()
        painter_path.addEllipse(rect)
        painter.setClipPath(painter_path)

        painter.drawPixmap(border_width, border_width, p)
        self.setPixmap(self.target)
您只需使用正确的参数创建实例:

    self.textDownQLabel = RoundLabelImage(
        urlpath=video.author_thumbnail, size=base_size, border_width=border_width, 
        border_color=QtGui.QColor(0, 30, 66)
    )
请注意,我使用了
steel_blue.png
图像的颜色作为边框:因为它只是一个具有一种颜色的图像,并且您总是使用相同的源,因此使用QPixmap作为边框是毫无意义的

最后,正如我在代码中的一条注释所指出的,您确实应该而不是依赖可能在UI元素中阻塞(甚至可能引发异常)的函数。下载QWidget
\uuuuu init\uuuuu
中的任何内容肯定会被阻止,直到加载完成;这一点从一开始就错了,但是如果你有很多东西(或者连接速度慢),情况会更糟。

对异步下载进行一些研究(Qt为这些情况提供了QtNetwork模块,有数百篇关于它的帖子),在下载其网络内容之前创建项目,然后在下载完成后更新这些内容,通过适当的信号/插槽连接。

请尽量减少示例。您的问题似乎与url加载无关,并且使您的示例很难理解,因为它有很多代码,对于您所问的内容来说完全不必要。也就是说,问题在于您的“steel_blue.png”图像不是正方形的,而下载的图像是:由于您使用的是
KeepAspectRatio
,因此背景高度较小。在任何情况下,如果您只想在图像周围绘制一个圆形边框,那么您的实现显然要比应该的复杂得多。
    self.textDownQLabel = RoundLabelImage(
        urlpath=video.author_thumbnail, size=base_size, border_width=border_width, 
        border_color=QtGui.QColor(0, 30, 66)
    )