2011-06-28 19 views
6

trato de dibujar un rectángulo redondeado con drawRoundedRect método directamente en un QPixmap (motor sin hacer que implican aquí exepto pura Qt uno ...), hago doble comprobar el tamaño del rectángulo en comparación con el tamaño de mi mapa de píxeles:Qt rectángulo redondo, ¿por qué las esquinas son diferentes?

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

ver un montón de espacio ...

EDIT: un código

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 desactivada la transformación del mundo ...
  • I SET SET transformación a la unidad ...
  • I probado varios radio (1.0,2.0,3.0,4.0) ...
  • I cambiar el ancho de la pluma, color cepillo ...

¡Pero siempre termina con un rectomgle con 4 esquinas diferentes! Al igual que:

Radius = 3.0 in x and y

I directamente ouptut el mapa de píxeles en un archivo para asegurarse de que no estaba raspando durante la visualización de ... de la misma forma.

¿Alguien sabe sobre el rectángulo redondo Qt con radio pequeño? Vi algo sobre esto hace mucho tiempo, pero no recuerdo cómo lidiar con eso.

Respuesta

14

Parece que no está utilizando anti-aliasing (es decir, la sugerencia de renderizado QPainter::Antialiasing). Esta es una peculiaridad Qt que ocurre sin ella. Por lo que he visto/escuchado, los desarrolladores de Qt no están muy preocupados por arreglar esto (la mayoría de las personas quiere anti-aliasing de todos modos).

La solución (además de usar solo anti-aliasing) es dibujar el rect usted mismo con QPainter::drawLine() y QPainter::drawArc(). Puede que tenga que jugar con los números hasta que se vea bien: los cálculos rectos tienden a salir un píxel o dos. Además, puede encontrar que incluso con este método, la esquina inferior derecha nunca es exactamente igual que las otras esquinas.

Si te sientes algo ambicioso, podrías intentar solucionarlo y enviar un parche a Qt.

Actualización: Los resultados del dibujo del arco cambiaron en Qt 5. En mi experiencia, es una gran mejora.

+2

Jugué con antialising de otra manera para dibujar cosas (drwa path, arc ...). ¡Antialiasing con cosas tan pequeñas lo hacen valer! Y mi mejor oportunidad fue addind ~ 0.5 en cada una de las preguntas donde el enrutamiento puede producir un comportamiento extraño ... ¡Así que voy a aceptar el método de ** jugar con números **! – vrince

+2

Tenía el mismo problema. Usando 'QPainter p (this); p.setRenderHint (QPainter :: Antialiasing); p.setRenderHint (QPainter :: HighQualityAntialiasing); 'hizo el truco para mí. –

+0

cambiando el ancho de la pluma hace la magia !! – Ashish

0

intente jugar con sugerencias de render 1) desactivar antiAliasing; 2) habilita SmoothPixmapTransform

pero todavía no hay garantía de que ayude.

+0

dijo correcto, no hay garantía !! – Ashish

3

trate de añadir la mitad de un pixel compensado (por ejemplo .: 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); 

supongo que esto tiene que ver con el sistema de coordenadas de colocar un valor entero entre dos píxeles.

Si dibuja con antialiasing y utiliza un lápiz de 1 píxel de ancho, dibujar en coordenadas enteras exactas da como resultado líneas de 2 píxeles de ancho en su lugar. Solo con este desplazamiento de 0.5 píxeles obtendrás líneas que tienen exactamente 1 píxel de ancho.

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

Sé que este es un problema antiguo, pero para los usuarios llamar Qt5setRenderHint(QPainter::Qt4CompatiblePainting); en el QPainter parece resolver el problema.

Editar:

he encontrado una solución para la generación de un rectángulo redondeado perfecto junto con el color del borde y se ve el mismo que los rectángulos redondeados usados ​​por QPushButton 's frontera por ejemplo. Así es como he implementado el paintEvent para lograrlo:

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

les dejo esto porque me pareció un poco difícil de lograr este resultado:

enter image description here

1

mejor manera de dibujar no es RoundRect Camino. 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

me han tratado todas las recomendaciones desde respuestas aquí, pero nada funciona para mí. Pero en base a estos fragmentos de código he encontrado la siguiente solución:

Como valor predeterminado, establezca m_pPainter->setRenderHint(QPainter::Qt4CompatiblePainting, true) y solo para rectángulos redondeados con ancho% 2 == 0 desactívelo.

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); 
Cuestiones relacionadas