You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在paintEvent中绘制圆角矩形控件?圆角边框为何裁切变形?

自定义QLabel圆角边框裁切变形问题

左侧是仅使用styleSheet绘制的QLabel,右侧是尝试不依赖styleSheet、主要在paintEvent中绘制的同款标签。两者样式几乎一致,但圆角边框的上下左右端点出现裁切变形,请问遗漏了什么?

class PaintLabel : public QLabel
{
    Q_OBJECT
public:
    int borderRadius = 12;

    PaintLabel(QWidget* parent = nullptr) : QLabel(parent)
    { 
        QFont font = parent->font();
        font.setPixelSize(18);
        font.setWeight(QFont::Weight(900));
        setFont(font);
    };

    void paintEvent(QPaintEvent* event) override
    {
        //QWidget::paintEvent(event);
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing, true);
 
        // BACKGROUND
        painter.setBrush(QColor(Qt::red));
        painter.drawRoundedRect(rect(), borderRadius, borderRadius);
    
        // BORDER
        painter.setPen(QPen(QColor("#810004"), 2));
        painter.drawRoundedRect(rect(), borderRadius, borderRadius);

        // TEXT
        painter.setPen(Qt::white);
        painter.drawText(rect(), Qt::AlignCenter, text());
    }
};

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindowClass())
{
    ui->setupUi(this);

    QLabel* styleSheetLabel = new QLabel(this);
    styleSheetLabel->setGeometry(200, 200, 24, 24);
    styleSheetLabel->setStyleSheet(R"(
        background-color: red; 
        border: 2px solid #810004;
        border-radius: 12px;
        color: white;
        font-size: 18px;
        font-weight: 900;
    )");
    styleSheetLabel->setAlignment(Qt::AlignCenter);
    styleSheetLabel->setFixedSize(QSize(24, 24));
    styleSheetLabel->setText("!");
    styleSheetLabel->show();

    QLabel* paintLabel = new PaintLabel(this);
    paintLabel->setGeometry(240, 200, 24, 24);
    paintLabel->setFixedSize(QSize(24, 24));
    paintLabel->setText("!");
    paintLabel->show();
}

问题原因与解决方法

核心问题

直接使用控件的rect()绘制边框时,画笔宽度(2px)会有一半落在控件区域之外,这部分会被窗口裁切,导致圆角端点变形;同时背景和边框共用同一个矩形,也会导致视觉上的重叠干扰。

具体修正步骤

  • 调整边框绘制区域:将绘制边框的矩形向内偏移画笔宽度的一半,确保边框完全在控件内部。
  • 分离背景与边框的绘制逻辑:背景绘制时设置Qt::NoPen,避免多余边框;边框使用调整后的矩形。
  • 优化画笔样式:设置画笔的端点和衔接样式为圆角,让边框过渡更自然,匹配styleSheet的效果。

修改后的paintEvent代码

void paintEvent(QPaintEvent* event) override
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);

    const int penWidth = 2;
    QPen borderPen(QColor("#810004"), penWidth);
    // 设置圆角端点和衔接样式
    borderPen.setCapStyle(Qt::RoundCap);
    borderPen.setJoinStyle(Qt::RoundJoin);

    // 计算边框绘制区域:向内偏移画笔宽度的一半
    const QRect borderRect = rect().adjusted(penWidth/2, penWidth/2, -penWidth/2, -penWidth/2);
    // 背景使用原控件矩形,确保填充完整
    const QRect bgRect = rect();

    // 绘制背景
    painter.setBrush(QColor(Qt::red));
    painter.setPen(Qt::NoPen); // 取消背景的画笔,避免多余线条
    painter.drawRoundedRect(bgRect, borderRadius, borderRadius);

    // 绘制边框
    painter.setPen(borderPen);
    painter.drawRoundedRect(borderRect, borderRadius, borderRadius);

    // 绘制文字
    painter.setPen(Qt::white);
    painter.drawText(rect(), Qt::AlignCenter, text());
}

内容的提问来源于stack exchange,提问作者Cesar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:44:59