簡體   English   中英

Qt繪制一個帶邊框的填充圓角矩形

[英]Qt drawing a filled rounded rectangle with border

我想繪制一個帶圓角的矩形(所有 4 個角的邊框半徑相同),用特定顏色填充整個矩形,並使用單獨的邊框顏色(比如邊框寬 1 像素)。

根據我的觀察,Qt 提供了三種方法 - fillRectdrawRect以及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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM