0

As stated in the title, I do want to know if there is a proper way to hatch the QLabel which in my case is has the Geometry of QRect as you can see in my code.

I checked the documentation but I didn't understand how I can hatch the QLabel.

Here is an image of how it might the QLabel will look after hatching (different options):

img

Note: that I don't intend to load a QPixmap, and I'm looking for more neat approach.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Bilal
  • 3,191
  • 4
  • 21
  • 49
  • 2
    What do you actually mean by "hatch"? Do you intend some kind of effect animation? Can you provide an actual example, even if taken from some other context? – musicamante May 17 '22 at 07:51
  • @musicamante I mean by "*hatch*" to draw thin lines on top of the `QLabel` with a kind of slope as you can see in the image in the question. – Bilal May 17 '22 at 10:50
  • 1
    So, you want to draw a *pattern*? Besides, those pattern are somewhat different, while the last 3 might be repeated (*tiled*), the first one is not. As said, please try to make yourself more clear. – musicamante May 17 '22 at 11:27

1 Answers1

2

You can override QLabel's paintEvent and use QBrush with predefined BrushStyle pattern or define your pattern as tiny pixmap and use as a QBrush.

If you need pattern on top of text (as foreground) call super().paintEvent(event) before drawing it, if you need it below text (as background) call super().paintEvent(event) after.

from PyQt5 import QtWidgets, QtGui, QtCore

class LabelStandardPattern(QtWidgets.QLabel):

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        painter.save()
        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(QtGui.QBrush(QtCore.Qt.Dense6Pattern))
        painter.drawRect(self.rect())
        painter.restore()
        super().paintEvent(event)


class LabelUserPattern(QtWidgets.QLabel):

    def __init__(self, text="", parent = None):
        super().__init__(text, parent)
        image = QtGui.QImage(5,5, QtGui.QImage.Format_ARGB32)
        image.fill(QtCore.Qt.transparent)
        painter = QtGui.QPainter(image)
        painter.drawLine(0,0,2,2)
        self._brush = QtGui.QBrush(image)
        self._image = image

    def paintEvent(self, event):
        
        painter = QtGui.QPainter(self)
        painter.save()
        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(self._brush)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, False)
        painter.drawRect(self.rect())
        painter.restore()
        super().paintEvent(event)

if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    palette = app.palette()
    palette.setColor(QtGui.QPalette.Foreground, QtGui.QColor(QtCore.Qt.blue))

    label1 = LabelStandardPattern("Standard Pattern")
    label1.setPalette(palette)
    label1.setFont(QtGui.QFont("Arial", 20))
    
    label2 = LabelUserPattern("User Pattern")
    label2.setPalette(palette)
    label2.setFont(QtGui.QFont("Arial", 20))
    
    widget = QtWidgets.QWidget()
    layout = QtWidgets.QVBoxLayout()
    layout.addWidget(label1)
    layout.addWidget(label2)
    widget.setLayout(layout)
    widget.show()

    app.exec()
mugiseyebrows
  • 4,138
  • 1
  • 14
  • 15
  • 2
    Note that it's actually not necessary to override the paint event when using standard patterns: it's enough to create a new QBrush with the color and pattern, and set that brush for the Window palette role (or any backgroundRole set for the widget). The same also goes for a pixmap when using a tiled pattern. – musicamante May 17 '22 at 11:48