Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

[PyQt6][Windows OS] Custom paintEvent() doesn't fill the whole widget background in some size



  • Hi folks! Could you please help with the following trouble?
    I have a QWidget which I've set to have transparent background and I've drawn background via paintEvent().

    I have added child widgets to this one and while rendering it seems that custom paintEvent() fail to draw full background, or child widgets somehow cover it and prevents successful rendering.

    b6f5a365-d50e-4e27-b371-585b134d8efc-image.png

    Child widgets are added via uic.loadUi('path.ui', self)

    Example code:

        def __init__(self):
            super().__init__()
    
            # QGridLayout inside with 12 cells as shown on screenshot
            uic.loadUi(r'path.ui', self)
    
            self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground, True)
            self.setAttribute(QtCore.Qt.WidgetAttribute.WA_AlwaysStackOnTop, True)
            self.setWindowFlags(QtCore.Qt.WindowFlags.Window)
            self.setWindowOpacity(1.0)
            self.setWindowFlags(QtCore.Qt.WindowFlags.FramelessWindowHint)
            self.setBorderMargin(5)
            self.setCornerMargin(20)
            self.resize(600, 400)
    
            self.layout().setSpacing(20)
            self.layout().setVerticalSpacing(20)
            self.layout().setContentsMargins(15, 15, 15, 15)
    
        def paintEvent(self, event):       
            painter = QPainter(self)
            painter.setRenderHint(QPainter.RenderHints.Antialiasing)
    
            pen = QPen(QColor(8553090), 1)
            painter.setPen(pen)
            brush = QBrush(QColor(14079702))
            painter.setBrush(brush)
    
            path = QPainterPath()
            rect = event.rect()
            rect.adjust(2, 2, -2, -2)
            #path.addRoundedRect(QRectF(rect), 35, 35)
            path.addRoundedRect(QRectF(rect), 35, 35)
    
            painter.fillPath(path, painter.brush())
            painter.strokePath(path, painter.pen())
    
            super().paintEvent(event)
    
        def keyPressEvent(self, event):
            if event.keyCombination().key() == QtCore.Qt.Key.Key_Escape:
                self.close()
    

  • Lifetime Qt Champion

    Hi,

    The rectangle returned by the paint event contains the region that needs to be updated so if you need your whole widget to be repainted you should use your widget rect.



  • Hi @SGaist !
    If I switch from even.rect() to self.rect() the result is the same.



  • @SGaist, update: If I add some qss custom styling via, for example, self.setStyleSheet("border: 1px solid gray;"), and, then, paint this style via QStyle in paintEvent():

     def paintEvent(self, event):
            opt = QStyleOption()
            opt.initFrom(self)
            painter = QPainter(self)
            painter.setRenderHint(QPainter.RenderHints.Antialiasing)
    
            pen = QPen(QColor(8553090), 1)
            painter.setPen(pen)
            brush = QBrush(QColor(14079702))
            painter.setBrush(brush)
    
            path = QPainterPath()
            rect = QRectF(event.rect())
            rect.adjust(2, 2, -2, -2)
            path.addRoundedRect(QRectF(rect), 35, 35)
    
            painter.fillPath(path, painter.brush())
            painter.strokePath(path, painter.pen())
    
            self.style().drawPrimitive(QStyle.PrimitiveElement.PE_Widget, opt, painter, self)
    
            super().paintEvent(event)
    

    Then I have all pixels rendered:
    c31c6503-e243-4095-9c9b-f02c32d60de8-image.png

    Do you have some ideas why this can happen?


  • Lifetime Qt Champion

    Intriguing...

    Do you have the same issue with PySide2 ?



  • Hi, @SGaist ! I have partially reproduced this issue with PySide6:
    0fea2a68-8484-4e98-8c45-2a8962a03630-image.png

    You can see the weird white strip line in the middle of the widget.


Log in to reply