如何在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
相关产品推荐
相关产品推荐

