PyQt5 Fusion 样式按钮图标已损坏
PyQt5 Fusion Style Button Icons are broken
我想要一个切换按钮来根据切换状态显示不同的图像。该功能在默认 QApplication 样式 ('WindowsVista') 中运行良好。但是 WindowsVista 风格很难看,我宁愿使用 Fusion 风格。不幸的是,图像在 Fusion Style 中没有改变。
代码:
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 样式(左侧按钮向上,右侧按钮向下):
融合风格(左边按钮向上,右边按钮向下):
这似乎是一种默认行为,因为在 source code:
中看到了融合风格
# ...
案例CE_PushButtonLabel:
如果(const QStyleOptionButton *button = qstyleoption_cast(选项)){
QStyleOptionButton b(*按钮);
// 融合风格没有 PM_ButtonShiftHorizontal 和 PM_ButtonShiftVertical
<b>b.state &= ~(State_On | State_Sunken);</b>
QCommonStyle::drawControl(元素, &b, 画家, 小部件);
}
休息;
// ...
一个可能的解决方案是实现一个覆盖此行为的 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_())
我想要一个切换按钮来根据切换状态显示不同的图像。该功能在默认 QApplication 样式 ('WindowsVista') 中运行良好。但是 WindowsVista 风格很难看,我宁愿使用 Fusion 风格。不幸的是,图像在 Fusion Style 中没有改变。
代码:
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 样式(左侧按钮向上,右侧按钮向下):
融合风格(左边按钮向上,右边按钮向下):
这似乎是一种默认行为,因为在 source code:
中看到了融合风格# ...
案例CE_PushButtonLabel:
如果(const QStyleOptionButton *button = qstyleoption_cast(选项)){
QStyleOptionButton b(*按钮);
// 融合风格没有 PM_ButtonShiftHorizontal 和 PM_ButtonShiftVertical
<b>b.state &= ~(State_On | State_Sunken);</b>
QCommonStyle::drawControl(元素, &b, 画家, 小部件);
}
休息;
// ...
一个可能的解决方案是实现一个覆盖此行为的 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_())