Painting artifacts with drawForeground in a QGraphicsView with no frame shape

Maurizio Berti maurizio.berti at gmail.com
Mon Nov 16 16:14:51 GMT 2020


I need to paint some static content on a QGraphicsView with
drawForeground().

Unfortunately, it seems that unsetting the frame shape with
setFrameShape(NoFrame) creates some painting artifacts, as the drawn
contents get "buffered" and follow the scene contents when scrolling.

I'm attaching two images to demonstrate it. The first (scrollwork.png) is
the expected result, while the second (scrollbug.png) shows what happens
when scrolling.

Note that as soon as the widget is *fully* repainted (by changing screen,
resizing, unminimizing, unfocusing, etc) the painting is correct again.
Changing the style doesn't solve the problem.

It seems that this can be avoided by setting the stylesheet with
`QGraphicsView {border: none;}`, but I'd like to understand the following:

1. Is this a (known) bug? Is it (as I believe) a Qt bug or PyQt one?
2. Is there something that can be done to prevent this from happening,
except calling update() on the whole viewport everytime the view is
scrolled (which is what I believe is happening when using the stylesheet,
and I'm afraid it theoretically affects performance, which is very
important for this project)?

I can confirm the bug on Linux with PyQt 5.7 and 5.12.

The following is a simple example to reproduce it:

from PyQt5 import QtCore, QtGui, QtWidgets
from random import randrange

class Test(QtWidgets.QGraphicsView):
    def __init__(self):
        super().__init__()
        scene = QtWidgets.QGraphicsScene()
        self.setScene(scene)
        for r in range(10):
            r = scene.addRect(randrange(1000), randrange(1000),
                randrange(1000), randrange(1000))
            r.setBrush(QtGui.QColor(QtCore.Qt.GlobalColor(randrange(19))))
        self.setFrameShape(0)
        self.viewport().setObjectName('viewport')
        self.setStyleSheet('Test {border: none;}')

    def drawForeground(self, qp, rect):
        qp.save()
        qp.resetTransform()
        qp.setBrush(QtGui.QColor('orange'))
        rect = QtCore.QRect(20, 20, 100, 30)
        qp.drawRect(rect)
        qp.drawText(rect, QtCore.Qt.AlignCenter, 'Test')
        qp.restore()

import sys
app = QtWidgets.QApplication(sys.argv)
w = Test()
w.show()
sys.exit(app.exec_())

Thanks,
Maurizio
-- 
È difficile avere una convinzione precisa quando si parla delle ragioni del
cuore. - "Sostiene Pereira", Antonio Tabucchi
http://www.jidesk.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20201116/53c65e76/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: scrollwork.png
Type: image/png
Size: 1048 bytes
Desc: not available
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20201116/53c65e76/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: scrollbug.png
Type: image/png
Size: 1110 bytes
Desc: not available
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20201116/53c65e76/attachment-0001.png>


More information about the PyQt mailing list