使用Qt样式表更改状态更改图标



我试图支持我的应用程序的主题化,但我遇到了一个问题,我必须根据QPushButton的状态(默认、悬停、按下等)更改图标

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

因为悬停状态使用的背景需要一个来自我的深色主题的图标,所以我尝试使用以下方法将其更改为另一个:

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

当我这样做时,play_light.png会显示为它应该显示的,但在状态更改时不会更改为play_dark.png

在我的Python代码中,播放按钮在播放时变为停止按钮,所以在我的风格中,我使用自定义属性将其设置为该图标:

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

这对我来说也不会改变。所以,我在网上找到了一些代码来重置按钮的样式,看起来像这样:

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

我不想对每个单个按钮的单个状态更改使用此解决方法。你们以前遇到过这个问题吗?

谢谢你花时间看这个。

根据经验,可以在样式表中使用Q_PROPERTY设置的所有变量都是持久状态,并且只能设置一次

例如,如果您添加一个自定义边界半径并设置这样的样式表,您将看到圆角,然后设置一个空样式表,则您将发现小部件更改为原来的样子;qproperty xxx";,一旦设置好,如果没有明确更新,它就不会改变。此外;qproperty xxx"只能在默认选择器中设置。

将QToolButton继承为MyToolButton,以下是主要代码:

Q_PROPERTY(QIcon iconUp READ iconUp WRITE setIconUp NOTIFY iconChanged)
Q_PROPERTY(QIcon iconOver READ iconOver WRITE setIconOver NOTIFY iconChanged)
Q_PROPERTY(QIcon iconDown READ iconDown WRITE setIconDown NOTIFY iconChanged)
Q_PROPERTY(QIcon iconUpChecked READ iconUpChecked WRITE setIconUpChecked NOTIFY iconChanged)
Q_PROPERTY(QIcon iconOverChecked READ iconOverChecked WRITE setIconOverChecked NOTIFY iconChanged)
Q_PROPERTY(QIcon iconDownChecked READ iconDownChecked WRITE setIconDownChecked NOTIFY iconChanged)
protected:
    QIcon m_iconUp;
    QIcon m_iconOver;
    QIcon m_iconDown;
    QIcon m_iconUpChecked;
    QIcon m_iconOverChecked;
    QIcon m_iconDownChecked;
signals:
    void iconChanged();
bool event(QEvent *event) override {
    switch (event->type()) {
    case QEvent::MouseButtonPress:
    case QEvent::MouseButtonRelease:
    case QEvent::MouseButtonDblClick:
    case QEvent::Enter:
    case QEvent::Leave:
        reloadIcon();
        break;
    default:
        break;
    }
    return QToolButton::event(event);
}
void checkStateSet() override {
    reloadIcon();
}
void reloadIcon() {
    if (isChecked()) {
        if (isDown() && !m_iconDownChecked.isNull()) {
            setIcon(m_iconDownChecked);
            return;
        } else if (underMouse() && !m_iconOverChecked.isNull()) {
            setIcon(m_iconOverChecked);
            return;
        } else if (!m_iconUpChecked.isNull()) {
            setIcon(m_iconUpChecked);
            return;
        }
    }
    if (isDown() && !m_iconDown.isNull()) {
        setIcon(m_iconDown);
        return;
    } else if (underMouse() && !m_iconOver.isNull()) {
        setIcon(m_iconOver);
        return;
    } else if (!m_iconUp.isNull()) {
        setIcon(m_iconUp);
        return;
    } else {
        setIcon(QIcon());
    }
}

样式表示例:

MyToolButton {
    qproperty-iconUp: url(:/images/up.svg);
    qproperty-iconOver: url(:/images/hover.svg);
    qproperty-iconDown: url(:/images/pressed.svg);
}

想明白了。我把图标保存在表单上,这样我就知道哪些图标去了哪个,但在我的样式表中,我做了这样的事情:

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

然后在我悬停时:

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

当我更改自定义属性时,我仍然需要self.ui.playButton.setStyle(qApp.style())代码,但对于其他所有内容,这都很好。

设置qApp.style()不是一个好主意。试试这个(从C++转换):
button->style()->unpolish(button);
button->style()->polish(button);
button->update();

相关内容

  • 没有找到相关文章

最新更新