Qt round rectangle, why are the angles different?

I am trying to draw a round rectangle using the QPixmap method directly in QPixmap (no rendering engine includes only pure Qt one here ...), I double-check the size of the rectangle and the size of my pixmap

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

See a lot of space ...

EDIT: some code

 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 turned off the transformation of the world ...
  • I set the conversion of a set to one ...
  • I tried several radii (1.0.2.0.3.0.4.0) ...
  • I change the width of the pen, the color of the brush ...

But it always ends with a rectangle with four different angles! For instance:

Radius = 3.0 in x and y

I directly add pixmap to the file to be sure that I did not scrap it during the display ... of the same form.

Does anyone know about a Qt rectangle with a small radius? I have long seen something about this, but I don’t remember how to deal with it!

+6
source share
6 answers

It looks like you are not using anti-aliasing (i.e. the QPainter::Antialiasing render QPainter::Antialiasing ). This is Qt quirk that happens without it. From what I saw / heard, Qt developers are not terribly worried about fixing this (most people want smoothing anyway).

A workaround (besides using anti-aliasing) is to align yourself with QPainter::drawLine() and QPainter::drawArc() . You may need to play with numbers until they look right - direct calculations tend to go beyond a pixel or two. In addition, you may find that even with this method, the lower right corner will never be exactly the same as other corners.

If you are feeling quite ambitious, you can try to fix this and send the patch to Qt.

Update: Arc drawing results changed in Qt 5. In my experience, this is a big improvement.

+14
source

Try adding a half pixel offset (for example: 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 ); 

I believe this is because the coordinate system places an integer between two pixels.

If you draw using smoothing and use a pen with a width of 1 pixel, then a drawing with exact integer coordinates leads to the fact that instead, lines are built with a width of 2 pixels. Only with this 0.5-pixel offset will you get lines just 1 pixel wide.

 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 ); 
+3
source

I know this is an old problem, but for Qt5 users calling setRenderHint(QPainter::Qt4CompatiblePainting); on QPainter seem to solve the problem.

Edit:

I found a solution to create a perfect rounded rectangle along with the border color, and it looks just like the rounded rectangles used, for example, by the QPushButton border. Here's how I implemented paintEvent to achieve this:

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

I publish this because it was difficult for me to achieve this result:

enter image description here

+2
source

The best way to make RoundRect is the way to go. 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); } 
+1
source

try playing with rendering tips 1) disable antiAliasing; 2) enable SmoothPixmapTransform

but still does not guarantee that this will help.

0
source

I tried all the tips from the answers here, but nothing works for me. But based on these code snippets, I found the following solution:

By default, m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, true) and only for rounded rectangles with a width of% 2 == 0 disable it.

 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); 
0
source

Source: https://habr.com/ru/post/891559/


All Articles