Pregunta

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

¿Fue útil?

Solución

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.

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top