7

我尝试drawRoundedRect直接在 a 中使用方法绘制一个圆形矩形QPixmap(这里没有渲染引擎涉及纯 Qt 一个......),我仔细检查了矩形的大小与我的像素图的大小:

Pixmap : QSize(50, 73) 
Rectangle: QRect(0,0 48x11) 

看到足够的空间...

编辑:一些代码

pixmap = QPixmap(50,73); //example size that match my case
QRectF rect(0,0,48,11);

QPainter painter(&pixmap);
painter.setRenderHint(QPainter::TextAntialiasing);
painter.setWorldMatrixEnabled(false);
painter.setPen(QPen()); //no pen
painter.setBrush(QBrush(color));
painter.drawRoundedRect(rect, 2.0, 2.0);
  • 我禁用了世界转换...
  • 我将集合转换设置为统一...
  • 我尝试了几个半径(1.0,2.0,3.0,4.0)...
  • 我改变笔宽,画笔颜色......

但它总是以一个有 4 个不同角的矩形结束!像那样 :

x 和 y 中的半径 = 3.0

我直接将像素图输出到一个文件中,以确保在显示过程中没有刮掉它……相同的形状。

有人知道小半径的Qt圆形矩形吗?我很久以前就看到了它的东西,但我不记得如何处理它!

4

6 回答 6

15

看起来您没有使用抗锯齿(即QPainter::Antialiasing渲染提示)。这是一个没有它的 Qt 怪癖。据我所见/所闻,Qt 开发人员并不十分关心解决这个问题(大多数人都想要抗锯齿)。

解决方法(除了仅使用抗锯齿)是自己绘制矩形QPainter::drawLine()and QPainter::drawArc()。你可能不得不玩弄数字直到它看起来正确——直接计算往往会出现一两个像素。此外,您可能会发现即使使用此方法,右下角也不会与其他角完全相同。

如果你感觉有点野心勃勃,你可以尝试修复这个问题并向 Qt 提交补丁。

更新: Qt 5 中的弧绘图结果发生了变化。根据我的经验,这是一个很大的改进。

于 2011-06-28T14:53:57.183 回答
4

我知道这是一个老问题,但对于用户Qt5来说似乎可以解决问题。setRenderHint(QPainter::Qt4CompatiblePainting);QPainter

编辑:

我找到了一个与边框颜色一起生成完美圆角矩形的解决方案,它看起来与QPushButton's 的边框使用的圆角矩形相同。这就是我paintEvent实现这一目标的方式:

void MyButtonGroup::paintEvent(QPaintEvent * e)
{
    int borderSize = 5;
    QColor borderColor = Qt::red;
    QColor backgroundColor = Qt::blue;
    int borderRadius = 3;

    QPen pen;
    pen.setWidth(borderSize);
    pen.setColor(borderColor);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(pen);

    QRectF rect(rect().x() + borderSize / 2,
                rect().y() + borderSize / 2,
                rect().width() - borderSize,
                rect().height() - borderSize);


    if(borderSize % 2 == 0)
    {
        painter.drawRoundedRect(rect,
                                borderSize,
                                borderSize);
    }
    else
    {
        painter.drawRoundedRect(rect.translated(0.5, 0.5),
                                borderRadius,
                                borderRadius);
    }

    QBrush brush(backgroundColor);
    pen.setBrush(brush);
    painter.setBrush(brush);

    if(borderSize % 2 == 0)
    {
        painter.drawRoundedRect(rect,
                                borderRadius,
                                borderRadius);
    }
    else
    {
        painter.drawRoundedRect(rect.translated(0.5, 0.5),
                                borderRadius,
                                borderRadius);
    }

    QWidget::paintEvent(e);
}

我发布这个是因为我发现实现这个结果有点困难:

在此处输入图像描述

于 2014-09-22T18:32:07.923 回答
3

尝试添加半个像素偏移(例如:)rect.translated(0.5,0.5)

QRectF rect(0,0,48,11);
painter.setRenderHint(QPainter::Antialiasing,false);
painter.drawRoundedRect( rect.translated(0.5,0.5), 2.0, 2.0 );

我想这与在两个像素之间放置一个整数值的坐标系有关。

如果您使用抗锯齿绘制并使用 1 像素宽度的笔,则在精确的整数坐标处绘制会产生 2 像素宽度的线条。只有使用这个 0.5 像素的偏移量,您才能得到正好 1 像素宽的线条。

QRectF rect(0,0,48,11);
painter.setRenderHint(QPainter::Antialiasing,true);
painter.setBrush(Qt::NoBrush);
painter.setPen( Qt::white );
painter.drawRoundedRect( rect.translated(0.5,0.5), 2.0,2.0 );
于 2013-08-08T12:02:18.593 回答
2

绘制 RoundRect 的最佳方法是路径。 http://developer.nokia.com/community/wiki/Qt_rounded_rect_widget

void fillRoundRect(QPainter& painter, QRect r, int radius)
{
    painter.setRenderHint(QPainter::Antialiasing,true);

    QPainterPath rounded_rect;
    rounded_rect.addRoundRect(r, radius, radius);
    painter.setClipPath(rounded_rect);

    painter.fillPath(rounded_rect,painter.brush());     
    painter.drawPath(rounded_rect);     
}
于 2014-09-26T11:20:33.460 回答
0

尝试使用渲染提示 1) 禁用抗锯齿;2) 启用 SmoothPixmapTransform

但仍然不能保证它会有所帮助。

于 2011-06-28T14:30:16.873 回答
0

我已经尝试了此处答案中的所有提示,但对我没有任何帮助。但是基于这些代码片段,我找到了以下解决方案:

作为默认设置m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, true),仅适用于 width%2==0 的圆角矩形禁用它。

QRect rect = ConvertRectangle(rectangle);

int nPenWidth = m_pPainter->pen().width();
if ( nPenWidth % 2 == 0 )
    m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, false);

m_pPainter->drawRoundedRect(rect, dbRadiusX, dbRadiusY);

if ( nPenWidth % 2 == 0 )
    m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, true);
于 2014-12-03T13:43:44.020 回答