QGraphicsView et QGraphicsItem: ne mettez pas l'élément à l'échelle lors de la mise à l'échelle

StackOverflow https://stackoverflow.com/questions/1222914

Question

J'utilise les QGraphicsView et les QGraphicsItem de Qt & 180; existe-t-il un moyen de ne pas redimensionner la représentation graphique de l'élément dans la vue lorsque le rectangle de vue est modifié, par ex. lors du zoom avant. Le comportement par défaut est que mes éléments sont redimensionnés par rapport à mon rectangle de vue.

Je voudrais visualiser les points 2d qui devraient être représentés par un rectangle fin qui ne devrait pas être redimensionné lors du zoom dans la vue. Consultez un logiciel de modélisation 3D typique à titre de référence, où les points de sommet sont toujours affichés à la même taille.

Merci!

Était-ce utile?

La solution

Définissez l'indicateur QGraphicsItem :: ItemIgnoresTransformations de QGraphicItem sur true ne fonctionne pas pour vous?

Autres conseils

J'ai eu le même problème et il m'a fallu un certain temps pour le résoudre. Voici comment je l'ai résolu.

Étendez une classe QGraphicsItem, remplacez paint (). Dans la zone de dessin (), réinitialisez le facteur de mise à l'échelle de la transformation sur 1 (m11 et m22) et enregistrez m11 (facteur de mise à l'échelle x) et m22 (facteur de mise à l'échelle y) avant la réinitialisation. Ensuite, dessinez comme vous le feriez normalement, mais multipliez votre x par m11 et y par m22. Cela évite de dessiner avec la transformation par défaut, mais calcule explicitement les positions en fonction de la transformation de la scène.

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
}

Le bloc de code suivant dessine avec la transformation par défaut

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

Vous pouvez essayer les deux pour voir la différence. J'espère que cela t'aides.

Que diriez-vous de cela:

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

Comme vous pouvez le constater, le texte est redimensionné mais pas le rectangle. Notez que cela n'empêche pas uniquement la mise à l'échelle du rectangle, mais également d'autres transformations.

J'ai découvert que si je dérive une nouvelle classe et réimplémente la fonction paint, je peux le faire

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

C’est la meilleure façon de le faire que j’ai trouvée jusqu’à présent, mais je continue de bricoler.

La solution suivante a parfaitement fonctionné pour moi:

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

Nous pouvons également multiplier la scaleValue par d'autres mesures que nous souhaitons maintenir de taille constante en dehors de l'environnement de sauvegarde / restauration.

    QPointF ref(500, 500);
    QPointF vector = scaleValue * QPointF(100, 100);
    painter->drawLine(ref+vector, ref-vector);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top