Python 如何更改QPalette的当前颜色组
我试图更改Qpalete的当前颜色组,但Qpalete的setCurrentColorGroup方法似乎根本不起作用 我正在运行以下代码:Python 如何更改QPalette的当前颜色组,python,windows,qt,pyside,qpalette,Python,Windows,Qt,Pyside,Qpalette,我试图更改Qpalete的当前颜色组,但Qpalete的setCurrentColorGroup方法似乎根本不起作用 我正在运行以下代码: app = QtGui.QApplication(sys.argv) button = QPushButton() svgWidget = QSvgWidget(resources_paths.getPathToIconFile("_playableLabels/42-labelPlay-disabled-c.svg")) button.setLayou
app = QtGui.QApplication(sys.argv)
button = QPushButton()
svgWidget = QSvgWidget(resources_paths.getPathToIconFile("_playableLabels/42-labelPlay-disabled-c.svg"))
button.setLayout(QHBoxLayout())
button.layout().addWidget(svgWidget)
button.setFixedSize(QSize(300, 300))
print button.palette().currentColorGroup()
button.setEnabled(False)
print button.palette().currentColorGroup()
button.palette().setCurrentColorGroup(QPalette.ColorGroup.Normal)
print button.palette().currentColorGroup()
button.show()
print button.palette().currentColorGroup()
app.exec_()
这是我得到的输出:
PySide.QtGui.QPalette.ColorGroup.Normal
PySide.QtGui.QPalette.ColorGroup.Disabled
PySide.QtGui.QPalette.ColorGroup.Disabled
PySide.QtGui.QPalette.ColorGroup.Disabled
Process finished with exit code -1
所以。。。似乎setCurrentColorGroup什么都不做。关于如何更改当前的颜色组,有什么想法吗
提前谢谢
(顺便说一句,我正在Windows 7系统上运行PySide 1.2.4和Qt 4.8)您似乎试图更改图标的呈现方式,而不是小部件的绘制方式,因此调色板不是正确的API。相反,您应该使用,它允许不同的图像用于不同的和 要在
正常
和禁用
模式下使用相同的图像,请使用如下代码:
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap('image.svg'), QtGui.QIcon.Normal)
icon.addPixmap(QtGui.QPixmap('image.svg'), QtGui.QIcon.Disabled)
button = QtGui.QPushButton()
button.setIcon(icon)
palette = self.button.palette()
palette.setCurrentColorGroup(QtGui.QPalette.Normal)
palette.setColorGroup(QtGui.QPalette.Disabled,
palette.windowText(), palette.button(),
palette.light(), palette.dark(), palette.mid(),
palette.text(), palette.brightText(),
palette.base(), palette.window(),
)
button.setPalette(palette)
但是,您应该注意Qt文档中的警告:
自定义图标引擎可以自由忽略额外添加的像素贴图
因此,不能保证这将适用于所有平台上的所有小部件样式
更新:
如果上述方法不起作用,则可能意味着小部件样式正在控制禁用图标的呈现方式。相关的QStyle
API是,它返回根据和样式选项修改的pixmap的副本。似乎这个方法有时也会考虑调色板(与我上面所说的有些相反),但是当我测试这个方法时,它没有任何影响。我按如下方式重置调色板:
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap('image.svg'), QtGui.QIcon.Normal)
icon.addPixmap(QtGui.QPixmap('image.svg'), QtGui.QIcon.Disabled)
button = QtGui.QPushButton()
button.setIcon(icon)
palette = self.button.palette()
palette.setCurrentColorGroup(QtGui.QPalette.Normal)
palette.setColorGroup(QtGui.QPalette.Disabled,
palette.windowText(), palette.button(),
palette.light(), palette.dark(), palette.mid(),
palette.text(), palette.brightText(),
palette.base(), palette.window(),
)
button.setPalette(palette)
这使得按钮被禁用时颜色看起来正常,但图标仍然是灰色的。尽管如此,您可能还是想尝试一下,以防在您的平台上出现不同的情况(如果没有,请不要感到惊讶)
控制图标禁用的正确方法似乎是创建QProxyStyle
并覆盖generatedIconPixmap
方法。不幸的是,这个类在PyQt4中不可用,但我已经在PyQt5中对它进行了测试,它可以工作。因此,目前唯一可行的解决方案是升级到PyQt5,并使用QProxyStyle
。下面是演示如何实现它的演示脚本:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class ProxyStyle(QtWidgets.QProxyStyle):
def generatedIconPixmap(self, mode, pixmap, option):
if mode == QtGui.QIcon.Disabled:
mode = QtGui.QIcon.Normal
return super(ProxyStyle, self).generatedIconPixmap(
mode, pixmap, option)
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.button = QtWidgets.QPushButton(self)
self.button.setIcon(QtGui.QIcon('image.svg'))
self.button2 = QtWidgets.QPushButton('Test', self)
self.button2.setCheckable(True)
self.button2.clicked.connect(self.button.setDisabled)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.button)
layout.addWidget(self.button2)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setStyle(ProxyStyle())
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())
palete()
方法是const&
——也就是说,在python术语中,它返回一个副本,而不是一个引用。因此,您需要修改返回的调色板,然后使用按钮。setPalette(调色板)
应用更改。但是,使用setCurrentColorGroup
仍然不太可能有任何效果,因为该按钮仍将被禁用。此外,您还需要注意,某些样式不会对所有类型的图形使用调色板(这主要影响某些版本的Windows和OSX)。也许你应该解释一下用这种方式使用调色板想要达到什么目的。@ekhumoro我得到了一个按钮(QPushButton的一个平面无边界子类),它使用svg作为图标。源svg有一个红色背景,当我禁用按钮时,背景变成灰色。我不希望图标颜色被扭曲。我不知道禁用按钮时按钮是如何改变颜色的,但我发现它应该与调色板有关,所以我尝试将调色板的currentColorGroup设置为正常(而不是禁用),但它没有任何作用…@ekhumoro我使用的是PySide,所以我没有常量变量或指针之类的东西。我验证了每次调用button.palette()都会得到相同的Qpalete实例,但这可能只是一个包装器?我将按照您的建议尝试使用setPalette()。@ekhumoro它也不起作用。。。事实上,创建一个Qpalete,然后在其上使用setCurrentColorGroup也没有任何作用。我发现这真的很有意思:/NO,你通过Python使用Qt,所以C++签名总是相关的。如果您不理解这一关键点,就永远无法有效地使用PySide/PyQt。在Python中,修改一个可变对象(如列表)的副本,不会修改原始- C++并没有什么不同。因此,如果Qt方法返回一个常量&
,那么在PySide中,您将获得一个副本;但是如果它返回一个指针,你就得到了原始的。PySead只是一个围绕C++库的薄包装。调用PySide方法总是调用Qt中完全相同的方法。您好!我正是这样使用QIcon的:cls.PlayEnabledIcon=QIcon(resources\u path.getPathToIconFile(“\u playelabels/42 labelPlay enabled.svg”))cls.PlayEnabledIcon.addFile(resources\u path.getPathToIconFile(“\u playelabellable-disabled-c.svg”),mode=QIcon.disabled)
我的红色图标仍呈现为灰色。@GuillermoAres。正如我所说:“不能保证这将适用于所有平台上的所有小部件样式”。我在我的答案中添加了更多的信息,建议可能的解决方法。我读到了,但我知道事实上它并没有忽略我为QIcon.Disabled
模式添加的文件,因为它与我为QIcon.Normal
设置的文件有很大不同(首先是“播放”)三角形,另一个是感叹号)。禁用时,它确实会显示感叹号,但会将问号的颜色从红色更改为灰色。我见过Qt自动改变禁用按钮图标的颜色,这就是为什么我认为它可能与调色板有关,但可能是引擎本身。对我来说太晦涩了。谢谢你的耐心!:)顺便说一句,我真的不知道该怎么处理这个问题。有点乱。既然你在这方面似乎比我更有经验。。。我应该把你的答案标记为正确吗?