Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt4: tinting a QIcon

What is the easiest way to apply a color tint to a QIcon in Qt4/PyQt4? I have several monochrome QPixmaps which I'd like to re-color based on the properties of their associated objects.

like image 687
ChrisB Avatar asked Dec 21 '22 15:12

ChrisB


2 Answers

You can paint over your pixmap. Just choose a composition mode that's appropriate for your goal.

Below is a simple Tinter tool. applyTint method is the interesting part. This uses Overlay composition.

import sys
from PyQt4 import QtGui, QtCore

class Tinter(QtGui.QWidget):
    def __init__(self, image, parent=None):
        super(Tinter, self).__init__(parent)

        self.pixmap = QtGui.QPixmap(image)

        self.normal = QtGui.QLabel()
        self.normal.setPixmap(self.pixmap)
        self.tinted = QtGui.QLabel()

        self.red = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.red.setRange(0, 255)
        self.red.sliderMoved.connect(self.applyTint)
        self.green = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.green.setRange(0, 255)
        self.green.sliderMoved.connect(self.applyTint)
        self.blue = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.blue.setRange(0, 255)
        self.blue.sliderMoved.connect(self.applyTint)
        self.alpha = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.alpha.setRange(0, 255)
        self.alpha.setValue(128)
        self.alpha.sliderMoved.connect(self.applyTint)


        controlLayout = QtGui.QFormLayout()
        controlLayout.addRow('red', self.red)
        controlLayout.addRow('green', self.green)
        controlLayout.addRow('blue', self.blue)
        controlLayout.addRow('alpha', self.alpha)

        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.normal)
        layout.addWidget(self.tinted)
        layout.addLayout(controlLayout)
        self.setLayout(layout)

        self.applyTint()

    def applyTint(self):
        temp = QtGui.QPixmap(self.pixmap)
        color = QtGui.QColor(self.red.value(),
                             self.green.value(),
                             self.blue.value(),
                             self.alpha.value())
        painter = QtGui.QPainter(temp)
        painter.setCompositionMode(painter.CompositionMode_Overlay)
        painter.fillRect(temp.rect(), color)
        painter.end()
        self.tinted.setPixmap(temp)

app = QtGui.QApplication(sys.argv)

main = Tinter('so.jpg')
main.show()

sys.exit(app.exec_())

enter image description here

like image 105
Avaris Avatar answered Dec 28 '22 09:12

Avaris


If the icon can be displayed in its own widget (such as a QLabel), then a simple solution would be to apply a QGraphicsColorizeEffect.

Here's a simple demo:

from random import randint
from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.label = QtGui.QLabel(self)
        self.label.setPixmap(QtGui.QPixmap('image.jpg'))
        self.button = QtGui.QPushButton('Tint', self)
        self.button.clicked.connect(self.handleButton)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.label)
        layout.addWidget(self.button)

    def handleButton(self):
        if self.label.graphicsEffect() is None:
            self.effect = QtGui.QGraphicsColorizeEffect(self)
            self.effect.setStrength(0.6)
            self.label.setGraphicsEffect(self.effect)
        self.effect.setColor(QtGui.QColor(
            randint(0, 255), randint(0, 255), randint(0, 255)))

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
like image 32
ekhumoro Avatar answered Dec 28 '22 09:12

ekhumoro