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

时间:2016-10-29 11:46:40

标签: qt qt-designer qstylesheet

我试图在悬停时更改QpushButton的图标并按下,我使用QtDesigner和样式表。 我试过这个

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

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

但它不起作用。

I tried setting it from QtDesigner Menu 但它也不起作用。

6 个答案:

答案 0 :(得分:3)

不幸的是,这是一个bug of Qt仍然没有修复。对该错误的评论中有一个workaround suggestion,基本上您可以使用空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;
}

但最终的结果看起来......真的不太令人满意。如果使用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;
}

然后在您的代码中的某个位置设置UI,您可以执行以下操作:

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

宾果游戏 - 您可以在悬停时取消按钮的图标并取消悬停!

答案 1 :(得分:2)

阅读本文并遇到类似问题后。这是我在c ++中的工作,没有使用设计器的样式表。

1>我创建了一个图标,一个被按下,一个图标被正常显示。在您的情况下,我们将其作为悬停条件解决。

2>将图标添加到资源文件。

3>使用以下代码作为参考...

其中Add_PB是QPushButton。

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

这里的关键是可以使用setStyleSheet设置不同条件的不同图标。在CSS字符串中使用*运算符或“通用选择器”之前,我无法获得上述代码。

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

答案 2 :(得分:0)

我在设计师中制作了它,来自ui _... h file:

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);

答案 3 :(得分:0)

在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);}");

答案 4 :(得分:0)

我知道这是一个古老的问题,但我认为它可能仍然有用。

要获得一个默认情况下仅显示图像的按钮,然后悬停时显示另一个图像,我尝试在编辑器中设置一个图标并使用onSelectedonActive等。但是自然地,它不起作用。

所做的工作是从@JosephFarrish和@goerge汲取灵感的,因此首先要归功于他们。我决定将答案发布为“切实可行的”解决方案。

对于特定的按钮,我有2张图片:

  • 默认
  • 显示的一个

enter image description here

  • 并持续显示悬停效果

enter image description here

我针对特定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;
}

如您所见,ic-exploreic-explore-hover被添加到我的资源文件中,如下所示:

enter image description here

实际图标在根项目文件夹中,在名为icons的文件夹中。图标的前缀由:/icons/给出,这恰好与icons文件夹名称相同。

注意CSS,我设置了QPushButton的宽度和高度。

答案 5 :(得分:0)

我认为值得一提的是,截至发布此答案时,已批准的答案中提到的错误似乎已得到修复。我的按钮有以下样式表宏。这使按钮图标在悬停并按下时正确更改。

#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 ");"\
"}"

我使用 setStyleSheet 函数将其应用于我的每个 QPushButton,将每个状态的三个不同图像传递到宏中。

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

希望这会有所帮助!