[SOLVED] How to fill a QRect and remove a smaller QRect out of it?



  • I am trying to draw a mask around a selection made on a document with a QRubberband.

    I created a QWidget and reimplemented the paintEvent() so that, whenever the mask ought to be visible, it is first painted with a semi-transparent black using QPainter().fillRect(), then the selected QRect (QRubberband.geometry()) should be removed from this freshly painted mask. I hoped a simple QPainter().eraseRect() would work, but it remove everything below that selection, i.e. not only the mask, but also the other widget below (the document). Then I bumped into the composition modes, but that didn't work out either. All I've been able to come up with so far is:
    @
    surface = self.parent().geometry()
    self.setGeometry(surface)
    self.painter.begin(self)
    self.painter.setCompositionMode(QtGui.QPainter.CompositionMode_SourceOver)
    self.painter.fillRect(surface, QtGui.QColor(100, 100, 100, 70))
    self.painter.setCompositionMode(QtGui.QPainter.CompositionMode_Clear)
    self.painter.fillRect(self.parent().rubberband.geometry(), QtGui.QColor(100, 100, 100, 100,))
    self.painter.end()@

    I tried other composition modes (xor, destination out, etc.) but no matter what I do, the second Painter().fillRect() adds colour to the previous layour or removes everything to leave pitch black only.

    I feel I am on the right track, but I could just be fooling myself into believing that. Can you save me?



  • OK it seems I found the solution:

    @ surface = self.parent().geometry()
    self.setGeometry(surface)
    path = QtGui.QPainterPath()
    path.setFillRule(QtCore.Qt.OddEvenFill)
    path.addRect(QtCore.QRectF(surface))
    path.addRect(QtCore.QRectF(self.parent().rubberband.geometry()))
    self.painter.begin(self)
    self.painter.setBrush(QtGui.QBrush(QtGui.QColor(100, 100, 100, 70)))
    self.painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 0, 80)))
    self.painter.drawPath(path)
    self.painter.end()@

    Although I wonder whether this is the simplest solution? I'm surprised QPainter does not has a fill mode that allows to invert or exclude an area.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.