Search code examples
pythonqtpysideqdialogpaintevent

How do I stop paintEvent from painting children widgets?


I'm trying to add rounded corners to a QDialog. I'm defining my own paintEvent method to create rounded corners. It's working, but it's adding rounded borders to everything. Even the cursor is getting a border. Is there any way to disable this behavior?

Example code:

from PySide import QtCore, QtGui


class RenameDialog(QtGui.QDialog):
    def __init__(self, parent=None, **kwargs):
        super(RenameDialog, self).__init__(
            parent=parent, f=QtCore.Qt.CustomizeWindowHint)
        self.fieldA = QtGui.QLineEdit(self)
        self.fieldB = QtGui.QLineEdit(self)

        self.setLayout(QtGui.QHBoxLayout())
        self.layout().addWidget(self.fieldA)
        self.layout().addWidget(self.fieldB)

        # Set background transparent.  Only items drawn in paintEvent
        # will be visible.
        palette = QtGui.QPalette()
        palette.setColor(QtGui.QPalette.Base, QtCore.Qt.transparent)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
        self.setPalette(palette)

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        fillColor = QtGui.QColor(75, 75, 75, 255)
        lineColor = QtCore.Qt.gray

        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.setPen(QtGui.QPen(QtGui.QBrush(lineColor), 2.0))
        painter.setBrush(QtGui.QBrush(fillColor))
        painter.drawRoundedRect(event.rect(), 15, 15)

I'm trying to do this with a paintEvent because:

  • QDialog stylesheets cannot use border-radius. Curved borders do show up, but corners are still visible.
  • QDialogs.setMask() works, but there is no way (that I know of) to anti-alias the mask.

Here is what that looks like:

borders everywhere


Solution

  • Paint events are sent to a window/widget with the precise rectangle that needs updating not the whole bounding rectangle of the widget. When you call event.rect() it returns the rectangle that needs updating (As far as I know)

    Try changing this line painter.drawRoundedRect(event.rect(), 15, 15) To this painter.drawRoundedRect(self.rect(), 15, 15)

    EDIT: You also need to add this line anywhere in the constructor self.setWindowFlags(QtCore.Qt.FramelessWindowHint)

    enter image description here

    Hope this helps.