I want to draw a rectangle with rounded corners (border radius same for all 4 corners) with a specific color filling the entire rectangle, and a separate border color (say border is 1 px wide).
From my observation, Qt provides three methods - fillRect
and drawRect
and drawRoundedRect
. I have tried them, they don't work like I want to. There is no method like fillRoundedRect
. Which means that I can draw a rounded rectangle but it won't be filled with the color I want.
How do I do it? And also, I read that due to some aliasing problems, the corners are often rendered as unequal. How do I set it as equal for all four? Will painter.setRenderHint(QPainter::Antialiasing)
suffice? Or do I have to do anything else?
Download Notebook. A rounded rectangle is the shape obtained by taking the convex hull of four equal circles of radius and placing their centers at the four corners of a rectangle with side lengths and . A filled rounded rectangle with (or. ) is called a stadium.
You can create a QPainterPath
, add the rounded rect to it, and then fill and stroke it:
QPainter p(this); p.setRenderHint(QPainter::Antialiasing); QPainterPath path; path.addRoundedRect(QRectF(10, 10, 100, 50), 10, 10); QPen pen(Qt::black, 10); p.setPen(pen); p.fillPath(path, Qt::red); p.drawPath(path);
Note that even with antialiasing, 1 px border will probably never really look good, especially on a low DPI desktop monitor, on a high DPI mobile device it will be almost invisible.
If you create the rectangle as QRectF(9.5, 9.5, 100, 50)
it will look better with 1 px antialiased border, because it will "snap" on the right pixel:
The answer above (from @dtech) works great, but can sometimes end up with an uneven border around the roundedRect. Using QPainter.strokePath()
instead of QPainter.drawPath()
can fix this issue.
Here is a python implementation of QPushButton
, with paintEvent
reimplemented:
# I use PySide6, but whatever library should work. from PySide6.QtWidgets import QPushButton from PySide6.QtGui import QPainter, QPainterPath, QBrush, QPen from PySide6.QtCore import Qt, QRectF class RoundedButton(QPushButton): def __init__(self, text, bordersize, outlineColor, fillColor): super(RoundedButton, self).__init__() self.bordersize = bordersize self.outlineColor = outlineColor self.fillColor = fillColor self.setText(text) def paintEvent(self, event): # Create the painter painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) # Create the path path = QPainterPath() # Set painter colors to given values. pen = QPen(self.outlineColor, self.bordersize) painter.setPen(pen) brush = QBrush(self.fillColor) painter.setBrush(brush) rect = QRectF(event.rect()) # Slighly shrink dimensions to account for bordersize. rect.adjust(self.bordersize/2, self.bordersize/2, -self.bordersize/2, -self.bordersize/2) # Add the rect to path. path.addRoundedRect(rect, 10, 10) painter.setClipPath(path) # Fill shape, draw the border and center the text. painter.fillPath(path, painter.brush()) painter.strokePath(path, painter.pen()) painter.drawText(rect, Qt.AlignCenter, self.text())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With