PDA

View Full Version : How to re-scale or changing the size of a QGrapicsScene



KristianKarl
9th August 2010, 13:18
I have this piece of code:


#include <QtGui>

class GPS_Site : public QGraphicsEllipseItem {
public:
GPS_Site(const QString& text, qreal lon, qreal lat) {
setZValue(2);
QGraphicsEllipseItem::setFlags(ItemIgnoresTransfor mations | ItemIsSelectable);
QGraphicsEllipseItem::setPos(lon, lat);
QGraphicsEllipseItem::setRect(-5, -5, 10, 10);
QGraphicsSimpleTextItem* label = new QGraphicsSimpleTextItem(text, this);
label->setFlags(ItemIgnoresTransformations | ItemIsSelectable);
label->setPos(2, 3);
}
};

class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow() {
QGraphicsScene* scene = new QGraphicsScene();
scene->addItem(new GPS_Site("Lower left: A very long text label, bla bla bla bla bla bla bla", 58.111, 24.111));
scene->addItem(new GPS_Site("Upper right: bla bla bla", 58.999, 24.999));
view = new QGraphicsView(scene);
view->setScene(scene);
QMatrix m(1.0, 0.0, 0.0, -1.0, 0.0, 0.0); // identity matrix with reversed Y-axis
view->setMatrix( m );
setCentralWidget(view);
}
protected:
virtual void wheelEvent(QWheelEvent* event) {
qreal scaleFactor = pow((double) 2, -event->delta() / 240.0);
view->scale(scaleFactor, scaleFactor);
}
private:
QGraphicsView* view;
};

int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow* mainWin = new MainWindow();
mainWin->show();
return app.exec();
}


The code, when run, depicts 2 geographical sites with gps coordinates, and labels.
The sites and labels are made scale invariant using ItemIgnoresTransformations.

The problem I have is, that the size set by QGraphicsScene is too large, and the reason for this are the long labels used. The rendered scene puts the sites too close to one another.

What I would like to achieve, is an initial scene size that big enough to encompass the 2 sites (ignoring the label items sizes and positions).

50485047
The first image shows the 1 case, the second shows something what I would like to have.

I have tried so many combinations of sceneRect, mapFromScene etc etc but with no proper solution.

Any tips or hints?

/Regards Kristian

Lykurg
9th August 2010, 13:27
You can't do much when to positions are that close. You only can zoom in. use a cosmetic painter that the text and circle doesn't change their size.

EDIT: see QPen::setCosmetic().

KristianKarl
9th August 2010, 18:34
Actually, I found a solution using an article that I found here at QtCentre: Smooth Panning and Zooming (http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_ Zooming)

From that article I wrote:

void Layout::FitNetworkInView() {
//Get the rectangle of the visible area in scene coords
QRectF visibleArea = mapToScene( rect() ).boundingRect();

//Get map area
QRectF r = myMap->GetMapRect();

//Scale the view
qreal scaleFactor = qMin( qAbs( visibleArea.width() / r.width() ), qAbs( visibleArea.height() / r.height() ) );
scaleFactor *= 0.9;
if ( scaleFactor > 0 ) {
scale( scaleFactor, scaleFactor );
} else {
scale( 1.0 / scaleFactor, 1.0 / scaleFactor );
}
SetCenter( r.center() );
}


Calling the function above will nicely fit my sites within the viewport.
/Kristian