我试图支持我的应用程序的主题化,但我遇到了一个问题,我必须根据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())
代码,但对于其他所有内容,这都很好。
button->style()->unpolish(button);
button->style()->polish(button);
button->update();