Qt – Change QPushButton Icon on hover and pressed

qstylesheet, qt, qt-designer

I'm trying to change the Icon of a QpushButton on hover and pressed, I'm using QtDesigner with stylesheets.
I tried this

QpushButton{       qproperty-icon:url(:/images/start.png);}QPushButton:hover{       qproperty-icon:url(:/images/start_hov.png);}

But it doesn't work.

I tried setting it from QtDesigner Menu
but it didn't work as well.

Best Solution

Unfortunately, it is a bug of Qt which is still not fixed. There's a workaround suggestion within the comments to that bug, basically you could use empty qproperty-icon and reserve the space necessary for it while actually changing background-image property instead:

QPushButton {    qproperty-icon: url(" "); /* empty image */    qproperty-iconSize: 16px 16px; /* space for the background image */    background-image: url(":/images/start.png");    background-repeat: no-repeat;}QPushButton:hover {    background-image: url(":/images/start_hov.png");    background-repeat: no-repeat;}

But the end result looks... not very satisfactory really. You can get much better results if you use C++ to change the button's icon at runtime, here's a simple example using event filter:

#include <QObject>#include <QPushButton>#include <QEvent>class ButtonHoverWatcher : public QObject{    Q_OBJECTpublic:    explicit ButtonHoverWatcher(QObject * parent = Q_NULLPTR);    virtual bool eventFilter(QObject * watched, QEvent * event) Q_DECL_OVERRIDE;};ButtonHoverWatcher::ButtonHoverWatcher(QObject * parent) :    QObject(parent){}bool ButtonHoverWatcher::eventFilter(QObject * watched, QEvent * event){    QPushButton * button = qobject_cast<QPushButton*>(watched);    if (!button) {        return false;    }    if (event->type() == QEvent::Enter) {        // The push button is hovered by mouse        button->setIcon(QIcon(":/images/start_hov.png"));        return true;    }    if (event->type() == QEvent::Leave){        // The push button is not hovered by mouse        button->setIcon(QIcon(":/images/start.png"));        return true;    }    return false;}

Then somewhere in your code setting up the UI you do something like this:

ButtonHoverWatcher * watcher = new ButtonHoverWatcher(this);ui->pushButton->installEventFilter(watcher);

And bingo - you get the button's icon changing on hover and unhover!