2009-08-03 10 views
7

Estoy utilizando Qt's QGraphicsView- y QGraphicsItem-subclases. hay una manera de no escalar la representación gráfica del elemento en la vista cuando se cambia el rectángulo de la vista, p. al hacer zoom. El comportamiento predeterminado es que mis elementos se escalen en relación con mi rectángulo de vista.QGraphicsView y QGraphicsItem: no escalar el elemento al escalar la vista rect

Me gustaría visualizar 2d puntos que deberían estar representados por un rectángulo delgado que no debería escalar al hacer zoom en la vista. Consulte un software típico de modelado en 3D para referencia, donde los puntos de vértice siempre se muestran con el mismo tamaño.

Gracias!

+1

también tener un pico en http://doc.trolltech.com/4.5/qpen.html#setCosmetic si está utilizando una pintura personalizada rutina – mpen

Respuesta

9

Establecer el indicador del elemento QGraphicsItem :: ItemIgnoresTransformations en true no funciona para usted?

+4

Este hecho asegura que el tamaño del artículo es correcto, pero al menos en mi caso las posiciones están apagadas después de la transformación. Por ejemplo, cuando dibujo un polígono en mi aplicación y agrego elementos de rectángulo infantil en una vista sin escala (1: 1), obtengo el siguiente resultado: http://grafit.mchtr.pw.edu.pl/~szczedar/ nozoom.png. Después de escalar y con el conjunto de banderas, se ve así: http://grafit.mchtr.pw.edu.pl/~szczedar/zoomout.png – neuviemeporte

+1

Los documentos dicen que el elemento con el conjunto de banderas permanece anclado al padre, pero Creé el objeto rect con el polígono como padre y no funcionó.Intenté también el elemento de mapa de bits subyacente como padre, sin cambios. – neuviemeporte

2

¿Qué tal esto:

#include <QtGui/QApplication> 
#include <QtGui/QGraphicsScene> 
#include <QtGui/QGraphicsView> 
#include <QtGui/QGraphicsRectItem> 

int main(int argc, char* argv[]) { 
    QApplication app(argc, argv); 
    QGraphicsScene scene; 
    scene.addText("Hello, world!"); 
    QRect rect(50, 50, 100, 100); 
    QGraphicsRectItem* recti = scene.addRect(rect); 
    QGraphicsView view(&scene); 

    // Set scale for the view 
    view.scale(10.0, 5.0); 

    // Set the inverse transformation for the item 
    recti->setTransform(view.transform().inverted()); 

    view.show(); 
    return app.exec(); 
} 

Como se puede ver el texto se amplía el rectángulo pero no lo es. Tenga en cuenta que esto no solo evita la escala del rectángulo sino también otras transformaciones.

1

He descubierto que si derivo una nueva clase y reimpliment la función de pintura que puedo hacer

void MyDerivedQGraphicsItem::paint(QPainter *painter, 
            const QStyleOptionGraphicsItem *option, 
            QWidget *widget) 
{ 
    double scaleValue = scale(); 
    double scaleX = painter->transform().m11(); 
    setScale(scaleValue/scaleX); 
    QGraphicsSvgItem::paint(painter,option,widget); 
} 

Ésta es la mejor forma de hacerlo que he encontrado hasta ahora, pero todavía estoy retoques alrededor.

+1

Hm. Esto no funcionó para mí (en mi caso estoy subclasificando QGraphicsEllipseItem). El elemento aún se agranda cuando acerco la vista. ¿Hiciste algo además de lo anterior? – estan

+0

Bah lo siento, realmente funcionó. Pero me interesaría si encontraras otra forma. Porque cuando acerco la vista rápidamente (usando la rueda de desplazamiento) puedo notar algo de parpadeo:/ – estan

+0

Lo siento, no, todavía tenía algunos problemas con él, pero se abandonó. – enriched

3

Me metí en el mismo problema, y ​​me tomó un tiempo para resolverlo. Así es como lo resolví.

Extienda una clase QGraphicsItem, anule la pintura(). Dentro de la pintura(), restablezca el factor de escala de la transformación a 1 (que son m11 y m22), y guarde el m11 (factor de escala x) y m22 (factor de escala y) antes del reinicio. Luego, dibuja como lo harías normalmente pero multiplica tu x con m11 e y con m22. Esto evita el dibujo con la transformación predeterminada, pero calcula explícitamente las posiciones de acuerdo con la transformación de la escena.

void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) 
{ 
    QTransform t = painter->transform(); 
    qreal m11 = t.m11(), m22 = t.m22(); 
    painter->save(); // save painter state 
    painter->setTransform(QTransform(m11, t.m12(), t.m13(), 
            t.m21(), 1, t.m23(), t.m31(), 
            t.m32(), t.m33())); 
    int x = 0, y = 0; // item's coordinates 
    painter->drawText(x*m11, y*m22, "Text"); // the text itself will not be scaled, but when the scene is transformed, this text will still anchor correctly 
    painter->restore(); // restore painter state 
} 

El siguiente bloque de código está drenando con la transformación por defecto

void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget) 
{ 
    int x = 0, y = 0; 
    painter->drawText(x, y, "Text"); 
} 

Puede probar ambos para ver la diferencia. Espero que esto ayude.

1

La siguiente solución funcionó perfectamente para mí:

void MyDerivedQGraphicsItem::paint(QPainter *painter, const StyleOptionGraphicsItem *option, QWidget *widget) 
{ 
    double scaleValue = scale()/painter->transform().m11(); 
    painter->save(); 
    painter->scale(scaleValue, scaleValue); 
    painter->drawText(...); 
    painter->restore(); 
    ... 
} 

También podemos multiplicar la scaleValue por otros mesures queremos mantener constante su tamaño fuera del entorno de guardar/restaurar.

QPointF ref(500, 500); 
    QPointF vector = scaleValue * QPointF(100, 100); 
    painter->drawLine(ref+vector, ref-vector);