Как изменить текущую цветовую группу для QPalette

Я пытаюсь изменить текущую цветовую группу для QPalette, но кажется, что метод setCurrentColorGroup в QPalette просто не работает.

Я запускаю этот код:

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 ничего не делает. Любые идеи о том, как я могу изменить текущую цветовую группу?

Заранее спасибо!

(Кстати, я использую PySide 1.2.4 с Qt 4.8 в системе Windows 7)

1 ответ

Решение

Кажется, вы пытаетесь изменить способ отображения значков, а не способ рисования виджетов, поэтому палитра не подходит для использования API. Вместо этого вы должны использовать QIcon, который позволяет использовать разные изображения для различных режимов и состояний.

Чтобы использовать одно и то же изображение для обоих Normal а также Disabled режимы, вы бы использовали такой код:

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)

Тем не менее, вы должны внимательно принять к сведению это предупреждение из документации Qt:

Пользовательские движки иконок могут игнорировать дополнительно добавленные растровые изображения.

Поэтому нет гарантии, что это будет работать со всеми стилями виджетов на всех платформах.

ОБНОВЛЕНИЕ:

Если описанный выше метод не работает, это, вероятно, означает, что стиль виджета управляет отображением отключенных значков. Подходящий QStyle API генерируется IconPixmap, который возвращает копию растрового изображения, модифицированного в соответствии с режимом пиктограмм и параметрами стиля. Кажется, что этот метод иногда может также принимать во внимание палитру (что несколько противоречит тому, что я говорил выше), но когда я проверял это, он не оказывал никакого влияния. Я сбрасываю палитру так:

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_())
Другие вопросы по тегам