0

I have been trying to create a basic QGraphicsEffect to change the colors of the widget, but first I tried to make an effect that does nothing like so:

class QGraphicsSepiaEffect(QtWidgets.QGraphicsEffect):
  def draw(painter):
    pixmap = sourcePixmap()
    painter.drawPixmap(pixmap.rect(), pixmap)

I am using PySide2. Though I checked all over the internet but couldn't find any sample, neither a template nor a real custom effect.

How can I write a basic effect to alter the colors of my widget?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Joan Venge
  • 315,713
  • 212
  • 479
  • 689

1 Answers1

1

As your question is basically how to create a custom effect then based on an example offered by the Qt community I have translated it to PySide2:

import random
import sys

from PySide2 import QtCore, QtGui, QtWidgets
# or
# from PyQt5 import QtCore, QtGui, QtWidgets


class HighlightEffect(QtWidgets.QGraphicsEffect):
    def __init__(self, offset=1.5, parent=None):
        super(HighlightEffect, self).__init__(parent)
        self._color = QtGui.QColor(255, 255, 0, 128)
        self._offset = offset * QtCore.QPointF(1, 1)

    @property
    def offset(self):
        return self._offset

    @property
    def color(self):
        return self._color

    @color.setter
    def color(self, color):
        self._color = color

    def boundingRectFor(self, sourceRect):
        return sourceRect.adjusted(
            -self.offset.x(), -self.offset.y(), self.offset.x(), self.offset.y()
        )

    def draw(self, painter):
        offset = QtCore.QPoint()
        try:
            pixmap = self.sourcePixmap(QtCore.Qt.LogicalCoordinates, offset)
        except TypeError:
            pixmap, offset = self.sourcePixmap(QtCore.Qt.LogicalCoordinates)

        bound = self.boundingRectFor(QtCore.QRectF(pixmap.rect()))
        painter.save()
        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(self.color)
        p = QtCore.QPointF(offset.x() - self.offset.x(), offset.y() - self.offset.y())
        bound.moveTopLeft(p)
        painter.drawRoundedRect(bound, 5, 5, QtCore.Qt.RelativeSize)
        painter.drawPixmap(offset, pixmap)
        painter.restore()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QWidget()
    lay = QtWidgets.QVBoxLayout(w)
    for _ in range(3):
        o = QtWidgets.QLabel()
        o.setStyleSheet(
            """background-color : {}""".format(
                QtGui.QColor(*random.sample(range(255), 3)).name()
            )
        )
        effect = HighlightEffect(parent=o)
        o.setGraphicsEffect(effect)
        lay.addWidget(o)
    w.show()
    w.resize(640, 480)
    sys.exit(app.exec_())

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • This doesn't compile, super takes 1 argument, 0 give, should be super(HighlightEffect, self) – Joan Venge Jan 29 '20 at 16:19
  • @JoanVenge What version of python do you use? I assume that if the OP does not indicate it then use the latest version of Python, that is python3 but it seems that you use python2. – eyllanesc Jan 29 '20 at 16:23
  • I am using 2.7. Then please specify the version in your answer for future readers. – Joan Venge Jan 29 '20 at 16:25
  • @JoanVenge MHO would be better for the OP to specify its version :-) so that those who try to respond know what limitations the answer must have. – eyllanesc Jan 29 '20 at 16:29
  • @JoanVenge Anyway I have already updated it to be compatible with python2 too – eyllanesc Jan 29 '20 at 16:30
  • Sorry, please give an example for PyQt5 – S. Nick Jan 29 '20 at 16:53
  • @S.Nick change `PySide2` to `PyQt5` in my example – eyllanesc Jan 29 '20 at 16:54
  • `pixmap = self.sourcePixmap(QtCore.Qt.LogicalCoordinates, offset)` - ... `argument 2 has unexpected type 'QPoint'` – S. Nick Jan 29 '20 at 16:57
  • @S.Nick Thanks for the observation, there seems to be an incompatibility in the sourcePixmap method between PySide2 and PyQt5 but I already corrected it, try it and tell me if it works for you or not. :-) – eyllanesc Jan 29 '20 at 17:02
  • @eyllanesc what do you mean now I want something specific? I didn't change the question here. If you mean the other question, there is a reason I asked them as separate questions because they are separate questions. – Joan Venge Jan 29 '20 at 19:16
  • @JoanVenge Okay, so I have confused the concepts since we were talking in 2 post. To avoid this confusion, what is wrong with my answer in this question according to your opinion or what is missing? – eyllanesc Jan 29 '20 at 19:18