I am in the process of learning PyQt5 by translating a previously written Tkinter music player application. One of the configuration options allows the user to set the background color of all buttons. However, three of the buttons (Play, Pause & Stop) are unique as they also display a corresponding image. The image consists of an icon on a transparent background where the icon is colored (Play=green, Pause=yellow, Stop=red) for when a given state is active or white if one of the other two states is active. Below is what the (active) Play button looks like on Tkinter for a couple of different background settings:
and
On Qt5 I have verified that the background color is being set correctly by commenting out the line that loads the image:
However, when the same image file from Tkinter is loaded, the background color is suddenly blocked in the sections of the image that are transparent:
When my initial attempt didn't work, I tracked down this post and modified my code from the way the original code was being done to the way suggested in the answer. However, in my case this made no difference. The code I'm using to test this is (with image load commented out):
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()
I'm still very much a novice on Qt but everything I've read so far seems to indicate that this should work. Can anyone spot what I'm doing wrong?
setStyleSheet()
always overwrites the previously set stylesheet for that widget, so you are basically ignoring the previous setStyleSheet()
call. Also, since you're setting the background-color
for the parent stylesheet, it will automatically propagate that background for its children (since stylesheets are, indeed, cascading).
To correctly set the stylesheet you have to set the background color and background image within the same call.
btn.setStyleSheet('''
#widget {
background-color: #b5abf4;
background-image: url(play_on.png);
}
''')
Since you'll probably want to set those backgrounds for all buttons and avoid setting the stylesheets individually each time, you can use object properties and the [property="value"]
selector in the parent stylesheet
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;
}
''')