[英]Qt drawing a filled rounded rectangle with border
我想繪制一個帶圓角的矩形(所有 4 個角的邊框半徑相同),用特定顏色填充整個矩形,並使用單獨的邊框顏色(比如邊框寬 1 像素)。
根據我的觀察,Qt 提供了三種方法 - fillRect
和drawRect
以及drawRoundedRect
。 我已經試過了,它們不像我想要的那樣工作。 沒有像fillRoundedRect
這樣的fillRoundedRect
。 這意味着我可以繪制一個圓角矩形,但它不會填充我想要的顏色。
我該怎么做? 而且,我讀到由於一些鋸齒問題,角落經常呈現不等。 我如何將它設置為所有四個相等? painter.setRenderHint(QPainter::Antialiasing)
就夠了嗎? 還是我必須做其他事情?
您可以創建一個QPainterPath
,向其添加圓角矩形,然后填充和描邊它:
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);
請注意,即使使用抗鋸齒,1 像素邊框也可能永遠不會真正好看,尤其是在低 DPI 桌面顯示器上,在高 DPI 移動設備上它幾乎不可見。
如果您將矩形創建為QRectF(9.5, 9.5, 100, 50)
它會在 1 px 抗鋸齒邊框下看起來更好,因為它會“捕捉”在正確的像素上:
上面的答案(來自@dtech)效果很好,但有時最終會在 roundedRect 周圍出現不均勻的邊框。 使用QPainter.strokePath()
而不是QPainter.drawPath()
可以解決這個問題。
這是QPushButton
的 Python 實現,重新實現了paintEvent
:
# 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())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.