QGraphicsView e QGraphicsItem: non ridimensionare l'elemento quando si ridimensiona la vista retta

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

Domanda

Sto usando le QGraphicsView - e QGraphicsItem di Qt. c'è un modo per non ridimensionare la rappresentazione grafica dell'elemento nella vista quando si cambia il rettangolo della vista, ad es. quando si esegue lo zoom. Il comportamento predefinito è che i miei elementi vengono ridimensionati in relazione al mio rettangolo di visualizzazione.

Vorrei visualizzare i punti 2d che dovrebbero essere rappresentati da un rettangolo sottile che non dovrebbe ridimensionare quando si ingrandisce la vista. Vedi un tipico software di modellazione 3d per riferimento in cui i punti di vertice sono sempre mostrati alla stessa dimensione.

Grazie!

È stato utile?

Soluzione

Impostare il flag QGraphicItem QGraphicsItem :: ItemIgnoresTransformations su true non funziona per te?

Altri suggerimenti

Ho avuto lo stesso problema e mi ci è voluto un po 'per capirlo. Ecco come l'ho risolto.

Estendi una classe QGraphicsItem, sovrascrivi paint (). All'interno della vernice (), reimpostare il fattore di ridimensionamento della trasformazione su 1 (che sono m11 e m22) e salvare m11 (fattore di ridimensionamento x) e m22 (fattore di ridimensionamento y) prima del ripristino. Quindi, disegna come faresti normalmente ma moltiplica la tua x con m11 e y con m22. Ciò evita di disegnare con la trasformazione predefinita, ma calcola esplicitamente le posizioni in base alla trasformazione della scena.

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
}

Il seguente blocco di codice viene disegnato con la trasformazione predefinita

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

Puoi provare entrambi a vedere la differenza. Spero che questo ti aiuti.

Che ne dici di questo:

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

Come puoi vedere, il testo è ingrandito ma il rettangolo no. Nota che ciò non impedisce solo il ridimensionamento del rettangolo ma e altre trasformazioni.

Ho scoperto che se ricavo una nuova classe e reinnovo la funzione di pittura, posso farlo

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

Questo è il modo migliore di farlo che ho trovato finora, ma sto ancora armeggiando.

La seguente soluzione ha funzionato perfettamente per me:

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

Possiamo anche moltiplicare scaleValue per altri messaggi che vogliamo mantenere costanti le sue dimensioni al di fuori dell'ambiente di salvataggio / ripristino.

    QPointF ref(500, 500);
    QPointF vector = scaleValue * QPointF(100, 100);
    painter->drawLine(ref+vector, ref-vector);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top