2010-12-10 16 views
10

Estoy usando Qt 4.7 QPainter para dibujar algunos polígonos, etc. en un widget. Espero alterar el sistema de coordenadas para que (0,0) esté en el centro de mi artilugio, y el eje x/y se comporte de una manera "cartesiana" estándar (es decir, y aumente yendo "arriba" y disminuya ") abajo"). En otras palabras, quiero que las coordenadas sean "matemáticas", como los "gráficos de computadora", como si supieras lo que quiero decir. :-)Usar ventana/ventana gráfica para voltear el eje y de QPainter

Estoy tratando de hacer esto usando setViewport() y setWindow() en lugar de hacer los cálculos yo mismo, ya que sería bueno poder simplemente llamar a los métodos de dibujo directamente con mis coordenadas.

Esto es lo que tengo hasta ahora:

// Setup coordinates 
double screenWidth = width(); 
double screenHeight = height(); 

double windowWidth = 100.0; 
double windowHeight = (screenHeight/screenWidth) * windowWidth; 

painter.setViewport(0, 0, screenWidth, screenHeight); 
painter.setWindow(-(windowWidth/2.0), -(windowHeight/2.0), windowWidth, windowHeight); 

// Draw stuff 
painter.setPen(Qt::NoPen); 
painter.setBrush(Qt::blue); 
painter.drawRect(-10, -10, 20, 20); 

Ahora bien, esto funciona bien, ya que dibuja un cuadrado azul agradable en el centro de la pantalla. El problema es que tengo que decir que la esquina superior izquierda es (-10, -10). Me gustaría poder hacerlo (-10, 10), ya que eso es lo que sería en las coordenadas cartesianas.

Intenté jugar con setWindow/setViewport para obtener este "salto del eje y", pero fue en vano. Esto parece una cosa realmente fácil/básica, pero después de recorrer los documentos de Qt y la web, ¡no puedo entenderlo!

Gracias,
Chris

Respuesta

22

Uso clase QMatrix. Especifica transformaciones 2D. QMatrix se establece en QPainter.

Pero recuerde, en su caso, si convierte coordenadas de su Widget a coordenadas cartesianas, que tendrá que poner en el primer punto (-10, -10)(no en (-10,10) como lo hizo mencionado) para dibujar un rect, que tiene centro en (0,0), porque el eje y ahora crece hasta y el eje X crece ahora derecha.

Todo lo que necesita es transformar su sistema coord esta manera:

  • traducir origen de (0,0) a la mitad del widget:
    alt text

  • escala eje Y por -1 factor:
    alt text

Aquí está el código, escrito en paintEvent() función de un widget:

QPainter pn(this); 

int w_2 = width()/2; 
int h_2 = height()/2; 

{ // X- and Y-Axis drawing 
    pn.setPen(Qt::blue); 
    pn.drawLine(0, h_2, width(), h_2);  // X-Axis 
    pn.drawLine(w_2, 0 , w_2, height()); // Y-Axis 
} 

QMatrix m; 
m.translate(w_2, h_2); 
m.scale(1, -1); 

pn.setMatrix(m); 
pn.setPen(Qt::NoPen); 
pn.setBrush(QBrush(Qt::blue, Qt::Dense4Pattern)); 
pn.drawRect(-10, -10, 20, 20); 

resultado:
alt text

actualización apr 07, 2014

Este pregunta fue hecha hace mucho tiempo y muchas cosas han cambiado desde entonces. Para aquellos que se hacen la misma pregunta hoy (comienzos de 2014), mi respuesta personal es que, desde Qt 4.3, es posible resolver el problema con el cambio de texto de forma más fácil.

Tienes razón. El texto también se filtra porque se dibuja con el mismo pintor. Puede dibujar texto al final, cuando todos los dibujos volteados estén hechos, si es posible. Este método no es conveniente debido a los nuevos cálculos de la posición de los textos. También tendrá que soltar la configuración para el pintor. Ahora le recomendaría usar QGraphicsView, debido al gran apoyo de la pintura en 2D. También para cada QGraphicsItemItemIgnoresTransformations se puede establecer el indicador, lo que le permite ignorar las transformaciones heredadas (es decir, su posición aún está anclada a su elemento principal, pero se ignoran las transformaciones padre o vista de rotación, zoom o corte). Este indicador es útil para mantener los elementos de etiquetas de texto horizontales y sin escala, por lo que seguirán siendo legibles si se transforma la vista de gráficos

+1

Correcto, sin embargo, es necesario mencionar que los textos también se voltean. ¡Eso no es lo más deseado! – bkausbk

+0

Gracias por la actualización;) – Stormenet

3

La respuesta anterior también cambiará el texto, "p" será "b". Para evitar eso, debes voltear el eje y antes de que se dibuje el texto, y debes cambiar el signo en y-coord para la posición del texto cuando lo dibujas. Esto es un poco feo, ¿o hay una forma mejor?

1

Como se indicó anteriormente, el texto del dibujo también aparece volteado al revés. Hay una solución fácil para él, ver abajo. Vamos a desactivar temporalmente la transformación del mundo para el dibujo de texto. Tenga en cuenta que el texto ya no tiene escala.

en su código de pintura queremos dibujar texto en coordenadas QPointF P;

Painter pn(this); 

// calculate the point with the transform 
QPointF p = pm.transform().map(P); 

// Disable Transform temporary 
pn.setWorldMatrixEnabled(false); 

// draw it ordinary, no scaling etc 
pn.drawText(p, QString("HI FRIENDS!")); 

// Enable the transform again 
pn.setWorldMatrixEnabled(true); 
Cuestiones relacionadas