简体   繁体   English

在悬停并按下时更改 QPushButton 图标

[英]Change QPushButton Icon on hover and pressed

I'm trying to change the Icon of a QpushButton on hover and pressed, I'm using QtDesigner with stylesheets.我试图在悬停和按下时更改 QpushButton 的图标,我正在使用 QtDesigner 和样式表。 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.我尝试从 QtDesigner Menu 设置它,但效果不佳。

Unfortunately, it is a bug of Qt which is still not fixed.不幸的是,这是Qt 的一个错误,仍未修复。 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:该错误的评论中有一个解决方法建议,基本上您可以使用空的qproperty-icon并保留所需的空间,同时实际更改background-image属性:

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:如果您在运行时使用 C++ 更改按钮的图标,您可以获得更好的结果,这是一个使用事件过滤器的简单示例:

#include <QObject>
#include <QPushButton>
#include <QEvent>

class ButtonHoverWatcher : public QObject
{
    Q_OBJECT
public:
    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:然后在设置 UI 的代码中的某处执行如下操作:

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

And bingo - you get the button's icon changing on hover and unhover!和宾果游戏 - 您可以在悬停和取消悬停时更改按钮的图标!

After reading this article and encountering similar issues.阅读本文后遇到类似问题。 This is my work around in c++ not using style sheet from designer.这是我在 C++ 中的工作,不使用设计师的样式表。

1>I create Icons one for being pressed and one for normal. 1>我创建图标,一个用于被按下,一个用于正常。 In your case we would address it as the hover condition.在您的情况下,我们会将其作为悬停条件处理。

2>Add the icons to the resource file. 2>将图标添加到资源文件中。

3>Use the following code for reference... 3>使用以下代码作为参考...

Where Add_PB is a QPushButton.其中 Add_PB 是 QPushButton。

Add_PB->setStyleSheet( "*{border-image: url(:/icons/maximize.bmp);}"  
":pressed{ border-image: url(:/icons/maximize_pressed.bmp);}"); 

The key take away here is you can use setStyleSheet to set diffrent icons for different conditons.这里的关键是您可以使用 setStyleSheet 为不同的条件设置不同的图标。 I couldnt get the above code to work until I used the * operator or "Universal Selector" in the CSS string.在我在 CSS 字符串中使用 * 运算符或“通用选择器”之前,我无法使上述代码工作。

Reference: http://doc.qt.io/qt-5/stylesheet-syntax.html参考: http : //doc.qt.io/qt-5/stylesheet-syntax.html

I maked it in designer, from ui_...h file:我在设计器中从 ui_...h 文件中创建了它:

QIcon icon;
icon.addFile(QStringLiteral(":/unpressed.png"), QSize(), QIcon::Normal, QIcon::Off);
icon.addFile(QStringLiteral(":/pressed.png"), QSize(), QIcon::Normal, QIcon::On);
pushButton->setIcon(icon);

In c++ , we can achieve it using the following code:在 c++ 中,我们可以使用以下代码实现它:

ui->button->setStyleSheet("QPushButton{border-image : url(./default_Img.png);} QPushButton:hover{border-image : url(./hover_Img.png); }"
                               "QPushButton:focus{border-image : url(./focus_Img.png);}");

I know this is an old question, but I think it may still be useful.我知道这是一个老问题,但我认为它可能仍然有用。

To get a button with only an image showing by default, then a different image on hover, I tried having an icon set in the editor and playing around with the onSelected , onActive , etc. but naturally, it didn't work.要获得默认情况下仅显示图像的按钮,然后悬停时显示不同的图像,我尝试在编辑器中设置一个图标并使用onSelectedonActive等,但很自然地,它不起作用。

What did work is inspired from @JosephFarrish and from @goerge so credit goes firstly to them.所做的工作受到@JosephFarrish 和@goerge 的启发,因此首先归功于他们。 I decided to post my answer as a 'tangible' solution.我决定将我的答案作为“切实的”解决方案发布。

For the particular push button, I have 2 images:对于特定的按钮,我有 2 张图片:

  • one shown by default默认显示一个

在此处输入图片说明

  • and on for a hover effect并打开悬停效果

在此处输入图片说明

My solution for a specific QPushButton is:对特定 QPushButton 的解决方案是:

QPushButton {
    border-image: url(:/icons/ic-explore);
    background-repeat: no-repeat;
    width: 32px;
    height: 32px;
}

QPushButton:hover {
    border-image: url(:/icons/ic-explore-hover);
    background-repeat: no-repeat;
}

as you can see, the ic-explore and ic-explore-hover are added to my resource file as shown below:如您所见, ic-exploreic-explore-hover已添加到我的资源文件中,如下所示:

在此处输入图片说明

where the actual icons are in the root project folder, in a folder named icons.实际图标位于项目根文件夹中的一个名为 icons 的文件夹中。 The prefix for the icons is given by :/icons/ and this coincidentally happens to be the same name as the icons folder name.图标的前缀由:/icons/ ,这恰好与icons文件夹名称相同。

Note with the CSS that I set the width and height of the QPushButton.请注意我设置 QPushButton 的宽度和高度的 CSS。

I think it's worth mentioning that as of the time of posting this answer, the bug mentioned in the approved answer appears to have been fixed.我认为值得一提的是,截至发布此答案时,已批准的答案中提到的错误似乎已得到修复。 I have the following stylesheet macro for my buttons.我的按钮有以下样式表宏。 This makes the button icons change correctly when they are hovered over and pressed.这使按钮图标在悬停并按下时正确更改。

#define BUTTON_STYLESHEET_TEMPLATE(not_pressed, hovered, pressed) "QPushButton {"\
"border-image: url(:icons/" not_pressed ");"\
"background-repeat: no-repeat;"\
"width: 65px;"\
"height: 56px;"\
"}"\
"QPushButton:hover {"\
"border-image: url(:icons/" hovered ");"\
"}"\
"QPushButton:pressed {"\
"border-image: url(:icons/" pressed ");"\
"}"

I applied this to each of my QPushButtons with the setStyleSheet function, passing the three different images for each state into the macro.我使用 setStyleSheet 函数将其应用于我的每个 QPushButton,将每个状态的三个不同图像传递到宏中。

button.setStyleSheet(BUTTON_STYLESHEET_TEMPLATE("not_pressed.png", "hovered.png", "pressed.png"));

Hopefully this helps!希望这会有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM