2011-06-28 75 views
6

我尝试绘制drawRoundedRect方法的圆角矩形直接在QPixmap(无渲染引擎涉及这里exept纯Qt的一个......),我仔细检查了矩形与我的像素图的大小尺寸: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); 
  • 我残疾人世界变换...
  • I SET设置变换到统一...
  • 我尝试了几种半径(1.0,2.0,3.0,4.0)...
  • 更改笔宽,刷色...

但它总是以4个不同角落的直肠结束!这样的:

Radius = 3.0 in x and y

我直接ouptut像素图的文件,以确保我的显示器......相同的形状期间没有刮了。

任何人都知道Qt圆角矩形小半径?我很久以前就看到过这种情况,但我不想回答这个问题!

回答

14

它看起来像你没有使用抗锯齿(即QPainter::Antialiasing渲染提示)。这是一个没有它的Qt怪癖。从我看到/听到的情况来看,Qt开发人员并不担心解决这个问题(无论如何,大多数人都希望进行反锯齿)。

解决方法(除了只使用反走样)是用QPainter::drawLine()QPainter::drawArc()自己绘制矩形。你可能需要玩数字,直到它看起来是正确的 - 直接计算往往会出现一个或两个像素点。此外,您可能会发现即使使用此方法,右下角也不会是,正如与其他角落一样。

如果你感觉有点雄心勃勃,你可以尝试解决这个问题并提交补丁给Qt。

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

+2

我用antialising玩其他方式来绘制东西(drwa路径,弧...)。用这种小东西进行抗锯齿使其值得!而我最好的投篮是加入〜0.5每一个地方都可能会产生怪异的行为......所以我会接受**数字**方法! – vrince

+2

有同样的问题。使用'QPainter p(this); p.setRenderHint(QPainter的::抗锯齿); p.setRenderHint(QPainter :: HighQualityAlliiasing);'为我做了诡计。 –

+0

改变笔的宽度做魔术! – Ashish

0

尝试玩渲染提示 1)禁用antiAliasing; 2)启用SmoothPixmapTransform

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

+0

正确的说,不保证!! – Ashish

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

我知道这是一个老问题,但对于Qt5用户呼吁QPaintersetRenderHint(QPainter::Qt4CompatiblePainting);似乎解决了问题。

编辑:

我找到了解决与边框颜色一起产生一个完美的圆角矩形,它看起来与由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); 
} 

我张贴这一点,因为我发现它有点难以实现这一结果:

enter image description here

1

做画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);  
} 
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);