Change icon on state change using Qt stylesheet

2019-03-02 21:53发布

问题:

I'm trying to support theming for my application, and I'm coming across a problem where I have to change icons based on the state of the QPushButton (default, hover, pressed, etc.). Here is what I use to set the icon for a QPushButton:

QPushButton#playButton {
    qproperty-icon: url(":/light/icons/play_light.png");
}

Because the hover state uses a background that requires an icon from my dark theme, I tried to change it to the other using this:

QPushButton#playButton:hover {
    qproperty-icon: url(":/dark/icons/play_dark.png");
}

When I do this, the play_light.png displays as it should, but it doesn't change to play_dark.png on state change.

In my Python code, the play button changes to a stop button on playback, so in my style, I set it to that icon using a custom property:

QPushButton#playButton[isPlaying="true"] {
    qproperty-icon: url(":/light/icons/stop_light.png");
}

This wouldn't change for me either. So, I found some code online to reset the style for the button, which looks like this:

self.ui.playButton.setProperty('isPlaying', not isEnable)
self.ui.playButton.setStyle(qApp.style())

I don't want to use this workaround for every single button for every single state change. Have you guys ran into this problem before?

Thanks for your time looking at this.

回答1:

Setting qApp.style() is not a good idea. Try this (convert from C++):

button->style()->unpolish(button);
button->style()->polish(button);
button->update();


回答2:

Figured it out. I kept the icons on my form so that I knew which icons went to which one, but in my stylesheet, I did something like this:

QPushButton#searchNext {
    qproperty-icon: none;
    image: url(":/light/icons/down_light.png"); 
}

Then on my hover:

QPushButton#searchNext:hover {
    image: url(":/dark/icons/down_dark.png");   
}

I still needed the self.ui.playButton.setStyle(qApp.style()) code when I change a custom property, but for everything else, this works fine.