Pregunta

Estoy usando Qt & # 180; s QGraphicsView - y QGraphicsItem -subclasses. ¿Hay alguna 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 acercar. El comportamiento predeterminado es que mis elementos se escalan en relación con mi rectángulo de vista.

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

¡Gracias!

¿Fue útil?

Solución

Establecer el QGraphicItem 'flag QGraphicsItem :: ItemIgnoresTransformations en true no funciona para usted?

Otros consejos

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

Extienda una clase QGraphicsItem, anule paint (). 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 restablecimiento. Luego, dibuja como lo harías normalmente, pero multiplica tu x con m11 e y con m22. Esto evita dibujar 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 se dibuja con la transformación predeterminada

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

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

¿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 puede ver, el texto está ampliado pero el rectángulo no. Tenga en cuenta que esto no solo evita la escala del rectángulo, sino también otras transformaciones.

Descubrí que si obtengo una nueva clase y vuelvo a implementar 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);
}

Esta es la mejor manera de hacerlo que he encontrado hasta ahora, pero todavía estoy jugando.

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 el scaleValue por otras medidas que queremos mantener su tamaño constante fuera del entorno de guardar / restaurar.

    QPointF ref(500, 500);
    QPointF vector = scaleValue * QPointF(100, 100);
    painter->drawLine(ref+vector, ref-vector);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top