python - PyQt5 Fusion 风格按钮图标损坏

标签 python pyqt pyqt5 qstyle

我想要一个切换按钮根据切换状态显示不同的图像。该功能在默认的 QApplication 样式(“WindowsVista”)中运行良好。但WindowsVista风格很难看,我宁愿使用Fusion风格。不幸的是,图像在融合风格中没有改变。

代码:

from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
                             QStyleFactory, QLabel)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QSize
from PyQt5 import Qt, QtCore
import sys

class Test(QMainWindow):
    def __init__(self, parent=None):
        super(Test, self).__init__(parent=parent)
        self.setGeometry(50,50,300,400)
        
        icon = QIcon()
        icon.addFile('red.png', state = QIcon.Off)
        icon.addFile('green.png', state = QIcon.On)
        button = QPushButton(parent = self)
        button.setCheckable(True)
        button.setIcon(icon)
        button.setIconSize(QSize(150,150))
        button.setGeometry(50,50,200,200)
        
        verString = 'PyQt version: ' + Qt.PYQT_VERSION_STR + '\n'
        verString += 'Qt version: ' + QtCore.qVersion()
        print(verString)
        label = QLabel(verString, parent = self)
        label.setGeometry(50, 250, 200, 150)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    #app.setStyle(QStyleFactory.create('fusion'))
    app.setStyle(QStyleFactory.create('windowsvista'))
    test = Test()        
    test.show()
    sys.exit(app.exec_() )

WindowsVista 样式(左侧按钮向上,右侧按钮向下):

enter image description here

融合风格(左侧按钮向上,右侧按钮向下):

enter image description here

最佳答案

由于 source code 中所示的融合样式,这似乎是默认行为。 :

# ...
case CE_PushButtonLabel:
    if (const QStyleOptionButton *button = qstyleoption_cast(option)) {
        QStyleOptionButton b(*button);
        // no PM_ButtonShiftHorizontal and PM_ButtonShiftVertical for fusion style
        <b>b.state &= ~(State_On | State_Sunken);</b>
        QCommonStyle::drawControl(element, &b, painter, widget);
    }
    break;
// ...

一个可能的解决方案是实现一个覆盖此行为的 QProxyStyle:

import sys

from PyQt5.QtCore import QSize, qVersion, PYQT_VERSION_STR
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (
    QApplication,
    QMainWindow,
    QPushButton,
    QStyleFactory,
    QLabel,
    QProxyStyle,
    QStyle,
    QCommonStyle,
)


class ProxyStyle(QProxyStyle):
    def drawControl(self, control, option, painter, widget):
        if control == QStyle.CE_PushButtonLabel:
            QCommonStyle.drawControl(self, control, option, painter, widget)
        else:
            super().drawControl(control, option, painter, widget)


class Test(QMainWindow):
    def __init__(self, parent=None):
        super(Test, self).__init__(parent=parent)
        self.setGeometry(50, 50, 300, 400)

        icon = QIcon()
        icon.addFile("red.png", state=QIcon.Off)
        icon.addFile("green.png", state=QIcon.On)
        button = QPushButton(parent=self)
        button.setCheckable(True)
        button.setIcon(icon)
        button.setIconSize(QSize(150, 150))
        button.setGeometry(50, 50, 200, 200)

        verString = "PyQt version: " + PYQT_VERSION_STR + "\n"
        verString += "Qt version: " + qVersion()
        print(verString)
        label = QLabel(verString, parent=self)
        label.setGeometry(50, 250, 200, 150)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle(QStyleFactory.create("fusion"))
    proxy = ProxyStyle(app.style())
    app.setStyle(proxy)
    test = Test()
    test.show()
    sys.exit(app.exec_())

关于python - PyQt5 Fusion 风格按钮图标损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63697206/

相关文章:

python - 暂停和恢复 QThread

python - 单击按钮时打开一个新窗口 || PyQt5

qt - Qt 支持 'Open a folder and highlight a particular file' 吗?

python - PyQt 中的动态小部件添加

python - pycharm 变量 Pane 中的隐藏值

python - 将元素添加到列表时运行代码

Python Kafka 模拟 Kafka Consumer 的返回类型

python - 使用 QThread 和 pyqtSignal,为什么不同线程中的进程会卡住 GUI?

python - 使用 pyqt5 和 matplotlib 进行图形滚动

python - VSCode : Auto import/import suggestions for Python dependencies from external libraries