PDA

View Full Version : QGraphicsItem scaling behaviour?



kachofool
31st December 2010, 22:25
Hey,

I'm having some strange behaviour while trying to scale a custom QGraphicsItem. Basically, I want to scale my item (its a simple QPainterPath thats shaped like a donut). I reimplemented the shape() function to make sure the shape as opposed to the bounding rectangle is the input sensitive region.

The item is centered at (0,0) in my scene. I want the user to click on the item, and drag towards (0,0) to scale down, and away (0,0) to scale up. Since my shape is a donut, this amounts to dragging towards or away from the center of the shape. I implemented this by overloading 'mouseMoveEvent' and getting mouse x,y coordinates to calculate the distance from (0,0), and then based on that, set the scale of the object.

So if I just calculate the distance, and move my mouse back and forth, this works as expected... my distance smoothly increases and decreases as I move the mouse around. If I actually scale the shape while moving the mouse though, it jumps back and forth (the distance), pixel to pixel... causing the scale to jump around as well... I can't figure out why.

I'd appreciate any help figuring out what's going on!




void Ring::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
double lkmx = event->pos().x();
double lkmy = event->pos().y();
double cen_dist = sqrt(pow(lkmx,2) + pow(lkmy,2));
qDebug() << "% distance from center: " << cen_dist/_radtyp << "\n";

// so if I uncomment the lines below qDebug()'s output will jump around, otherwise it'll be
// as expected
//_zoomfactor = cen_dist/_radtyp;
// this->setTransform(QTransform::fromScale(_zoomfactor, _zoomfactor), false);
}

kachofool
1st January 2011, 18:34
To anyone else having this issue, it was fixed by replacing

event->pos().x();

With

event->scenePos().x();

I guess during the scaling operation, the coordinates of the GraphicsItem were incorrect. I'd still like to understand what was going on if anyone has some insight, but there''s a band-aid fix.

pkohut
1st January 2011, 19:17
Haven't test this out, but from the docs - "event->pos(), Returns the mouse cursor position in item coordinates." If I'm interpreting that correctly then the position is relative to the item's current scale factor.

If that is correct then, simply taking the inverse of the item's scale and multiplying it by the event->pos, should give you the zoom factor relative to 1:1. I'll be diving into QGraphicsScene in a week or so myself, so will be sure to test this out too.

BTW, what is the variable _radtype?



void Ring::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
double dZoomFactor = QVector2d(event->pos()).length() * (1.0 / this->scale());
this->setScale(dZoomFactor);
}