PyQt5中图像的透明部分块背景颜色

Transparent part of image blocks background color in PyQt5

我正在通过翻译以前编写的Tkinter 音乐播放器应用程序来学习PyQt5。其中一个配置选项允许用户设置所有按钮的背景颜色。然而,其中三个按钮(播放、暂停和停止)是独一无二的,因为它们也显示相应的图像。该图像由透明背景上的一个图标组成,当给定状态处于活动状态时,该图标是彩色的(播放=绿色,暂停=黄色,停止=红色),如果其他两种状态之一处于活动状态,则该图标为白色。下面是(活动的)播放按钮在 Tkinter 上的几个不同背景设置的样子:

在 Qt5 上,我通过注释掉加载图像的行来验证背景颜色设置是否正确:

但是,当从 Tkinter 加载相同的图像文件时,背景颜色突然在图像的透明部分被遮挡:

当我最初的尝试没有奏效时,我找到了 this post 并将我的代码从原始代码的完成方式修改为答案中建议的方式。但是,就我而言,这没有任何区别。我用来测试的代码是(图像加载被注释掉):

import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication

class Example(QWidget):
    def __init__(self):
        super().__init__()
        btn = QPushButton(self)
        btn.resize(70,70)
        btn.move(115, 115)
        btn.setStyleSheet("background-color: #b5abf4")
        btn.setObjectName("widget")
        #btn.setStyleSheet("#widget{background-image: url(play_on.png)}")
        
        self.setGeometry(600, 300, 300, 300)
        self.setStyleSheet("background-color: white")
        self.show()
        
def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
    
if __name__ == '__main__':
    main()
 

我仍然是 Qt 的新手,但到目前为止我读过的所有内容似乎都表明这应该可行。谁能发现我做错了什么?

setStyleSheet() 总是覆盖之前为该小部件设置的样式表,因此您基本上忽略了之前的 setStyleSheet() 调用。此外,由于您正在为父样式表设置 background-color,它将自动为其子样式表传播该背景(因为样式表确实是 级联 )。

要正确设置样式表,您必须在同一调用中设置背景颜色 背景图像。

        btn.setStyleSheet('''
            #widget {
                background-color: #b5abf4;
                background-image: url(play_on.png);
            }
            ''')

由于您可能希望为所有按钮设置这些背景并避免每次都单独设置样式表,因此您可以使用对象属性和父样式表中的 [property="value"] 选择器

        btn.setObjectName("playButton")
        btn.setProperty('mediabutton', True)
        btn.setStyleSheet('''
            #playButton {
                background-image: url(play_on.png);
            }
            ''')
        
        self.setStyleSheet('''
            Example {
                /* set the background *only* for the parent widget */
                background-color: white;
            }
            QPushButton[mediabutton="true"] {
                /* set the background color for all push buttons that
                have the "mediabutton" property set to True */
                background-color: #b5abf4;
            }
        ''')