2009-08-03 10 views
7

Sto utilizzando Qt's QGraphicsView- e QGraphicsItem-sottoclassi. esiste un modo per non scalare la rappresentazione grafica dell'elemento nella vista quando il rettangolo di visualizzazione viene modificato, ad es. quando esegui lo zoom. Il comportamento predefinito è che i miei elementi si ridimensionano in relazione al mio rettangolo di visualizzazione.QGraphicsView e QGraphicsItem: non ridimensionare l'elemento durante il ridimensionamento della vista rect

Vorrei visualizzare i punti 2D che dovrebbero essere rappresentati da un rettangolo sottile che non dovrebbe ridimensionarsi quando si ingrandisce la vista. Vedere un tipico software di modellazione 3d come riferimento in cui i vertici vengono sempre mostrati alla stessa dimensione.

Grazie!

+1

Anche prendere un picco a http://doc.trolltech.com/4.5/qpen.html#setCosmetic se si sta utilizzando una vernice personalizzata di routine – mpen

risposta

9

Imposta il flag dell'articolo QGraphicsItem :: ItemIgnoresTransformations su true non funziona per te?

+4

Questo assicura infatti la dimensione della voce è corretta, ma almeno nel mio caso le posizioni sono disattivate dopo la trasformazione. Ad esempio, quando disegno un poligono nella mia app e aggiungo elementi rettangolo figlio in una vista non graduata (1: 1), ottengo il seguente risultato: http://grafit.mchtr.pw.edu.pl/~szczedar/ nozoom.png. Dopo il ridimensionamento e con il flag impostato, appare come segue: http://grafit.mchtr.pw.edu.pl/~szczedar/zoomout.png – neuviemeporte

+1

I documenti dicono che l'elemento con il flag set rimane ancorato al genitore, ma Ho creato l'oggetto rect con il poligono come genitore e non ha funzionato.Ho provato anche l'elemento pixmap sottostante come genitore, nessun cambiamento. – neuviemeporte

2

ne dite 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 si può vedere il testo viene scalato su ma il rettangolo non è. Si noti che questo non impedisce solo il ridimensionamento per il rettangolo ma e altre trasformazioni.

1

ho scoperto che se io derivare una nuova classe e reimpliment la funzione di vernice posso fare

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 io sono ancora armeggiare intorno.

+1

Hm. Questo non ha funzionato per me (nel mio caso sto sottoclassi QGraphicsEllipseItem). L'oggetto diventa ancora più grande quando si ingrandisce la vista. Hai fatto qualcosa oltre a quanto sopra? – estan

+0

Bah scusa, in realtà ha funzionato. Ma sarei interessato se hai trovato un altro modo? Perché quando zoomo velocemente la vista (usando la rotella di scorrimento) posso notare un po 'di sfarfallio:/ – estan

+0

Scusate, no, stavo ancora avendo qualche problema ma è stato abbandonato. – enriched

3

Ho avuto lo stesso problema e mi ci è voluto un po 'per capirlo. Questo è il modo in cui l'ho risolto.

Estendere una classe QGraphicsItem, sovrascrivere paint(). All'interno di paint(), ripristinare il fattore di scala della trasformazione su 1 (che sono m11 e m22) e salvare il 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 ey 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 è il disegno con la trasformazione di default

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

Si può provare sia per vedere la differenza. Spero che questo ti aiuti.

1

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 la scaleValue da altri mesures vogliamo mantenere la sua dimensione costante di fuori dell'ambiente di salvataggio/ripristino.

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