11
votes

Qgraphicsview and qgraphicsItem: n'éteignez pas l'élément lors de la mise à l'échelle de la vue

J'utilise QT's qgraphicsview - et qgraphicsitem -Subclasses. Existe-t-il un moyen de ne pas échoué 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 articles échouent par rapport à mon rectangle de vue.

Je voudrais visualiser des points 2D qui doivent être représentés par un mince rectangle qui ne doit pas échouer lors du zoom sur la vue. Voir un logiciel de modélisation 3D typique pour référence où les points de vertex sont toujours affichés à la même taille.

merci!


5 Réponses :


2
votes

Que diriez-vous:

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


0 commentaires


1
votes

J'ai trouvé que si je dérive une nouvelle classe et réimplimez la fonction de peinture, je peux 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);
}


4 commentaires

Hm. Cela n'a pas fonctionné pour moi (dans mon cas je suis sous-classement qgraphicsellipseitem). L'article devient toujours plus grand quand je zoomez la vue. Avez-vous fait quelque chose à côté de ce qui précède?


Bah Désolé, cela a réellement travaillé. Mais je serais intéressé si vous avez trouvé une autre manière? Parce que lorsque j'ai zoomer la vue rapide (à l'aide de la molette de défilement), je peux remarquer un certain scintillement: /


Désolé, non, j'avais encore des problèmes, mais cela a été abandonné.


Setcale Scédules Un redessinant de l'article, donc je suppose que votre code peut conduire à une boucle infinie. Et peintre-> transformer (). M11 () donne la balance si et uniquement si aucune rotation n'est appliquée à l'élément.



9
votes

Je suis entré dans le même problème, et cela m'a pris un certain temps pour le comprendre. C'est comme ça que je l'ai résolu.

Étendez une classe QGraphicsItem, remplacer la peinture (). À l'intérieur de la peinture (), réinitialisez le facteur de mise à l'échelle de la transformation sur 1 (qui sont M11 et M22) et enregistrez le facteur de mise à l'échelle M11 (X) et M22 (facteur d'échelle de Y) avant la réinitialisation. Ensuite, dessinez comme si vous le feriez normalement mais multipliez votre X avec M11 et Y avec 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. P> xxx pré>

Le bloc de code suivant est le dessin avec la transformation par défaut P>

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


2 commentaires

Une bonne réponse mais je pense que m11 sur qtransform la ligne d'instanciation doit être 1 à la place.


J'ai réparé que dans la réponse, merci @ canolgökel



2
votes

La solution suivante a fonctionné parfaitement pour moi:

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


0 commentaires