سؤال

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

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

I've found a work-around for now. You can hide the extra borders by using QPainter.eraseRect on the children and having the correct stylesheet set. I've also found that painting over the offending area with QPainter.fillRect works too.

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)

    # Sketchy fix:
    painter.eraseRect(self.childrenRect())
    # OR
    painter.fillRect(self.childrenRect(), QtGui.QBrush(fillColor))

This doesn't answer my original question though. I'd like to avoid this behavior rather than masking it. So I'm not going to mark this as the answer.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top