QGraphicsView e QGraphicsItem: non ridimensionare l'elemento quando si ridimensiona la vista retta
-
10-07-2019 - |
Domanda
Sto usando le 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!
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);