我尝试直接在drawRoundedRect
中绘制一个带有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);
但它始终以4个不同角落的直线结束!像那样:
我将pixmap直接输出到一个文件,以确保我在显示过程中没有刮掉它...相同的形状。
任何人都知道Qt小圆角矩形吗?很久以前我看到了它的一些东西,但我不记得如何处理它!
答案 0 :(得分:14)
看起来你没有使用抗锯齿(即QPainter::Antialiasing
渲染提示)。这是一个没有它的Qt怪癖。从我所看到/听到的情况来看,Qt开发人员并不十分关心修复这个问题(大多数人都想要抗锯齿)。
解决方法(除了使用消除锯齿之外)是使用QPainter::drawLine()
和QPainter::drawArc()
自行绘制矩形。你可能不得不玩数字,直到看起来正确 - 直接计算往往会出现一两个像素。此外,您可能会发现,即使使用此方法,右下角也不会与其他角落完全相同。
如果你感觉有点雄心勃勃,你可以尝试解决这个问题并向Qt提交补丁。
更新:在Qt 5中,圆弧绘制结果发生了变化。根据我的经验,这是一个很大的进步。
答案 1 :(得分: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 );
答案 2 :(得分:2)
我知道这是一个老问题,但Qt5
用户setRenderHint(QPainter::Qt4CompatiblePainting);
上的QPainter
似乎可以解决问题。
修改强>
我找到了一个解决方案,用于生成一个完美的圆角矩形和边框颜色,它看起来与QPushButton
边框使用的圆角矩形相同。这就是我实现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);
}
我发布这个是因为我发现实现这个结果有点困难:
答案 3 :(得分:1)
最好的方法是绘制RoundRect是Path。 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);
}
答案 4 :(得分:0)
尝试使用渲染提示 1)禁用antiAliasing; 2)启用SmoothPixmapTransform
但仍无法保证会有所帮助。
答案 5 :(得分:0)
我已经尝试了答案的所有提示,但对我没什么用。但基于这些代码片段,我找到了以下解决方案:
默认设置为m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, true)
,仅适用于宽度为%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);