PDA

View Full Version : Scrolling several QGraphicsViews with another widget



Sergex
24th November 2011, 14:18
Hello,

I am trying to gain control of the scrolling of my QGraphicsViews through another widget which in this case is a QGraphicsObject.

What I have is this GraphicsObject item that can be moved only horizontally. When my GraphicsViews are zoomed-in, the item has space to move. So I am trying to control the scrolling of the views with this item, so when I move the item to one side or the other, it will be like moving the views's scroll bars horizontally to one side or the other.

I have tried doing it like this:

- First I get the value of how much the item moved in either direction and send it through a signal, I connect that to a slot in my QGraphicsView class that has this :



void myView::scrollViewSlot(int dx)
{
int position = horizontalScrollBar()->value();
position += dx;
horizontalScrollBar()->setValue(position);
}


This is so that wherever the value of the horizontal scrollbar was, in this case I add to that value how much I would like to scroll and set the value of the horizontalScrollbar of the view, so it should move (scroll) the views. I understand that the value to add to the current horizontalScrollBar value must be well calculated by making tests no matter what the value is the views never scroll. I have made sure that the singal/slots are well connected and when I move the item, the slot gets reached with a value but the views don't move.

What am I missing to make this work properly?
Thanks.

Spitfire
24th November 2011, 16:15
Does the view move at all when you try to scroll it by some large number?
Maybe your dx is so small you can't see the movement?

Sergex
24th November 2011, 16:21
Thanks! I was trying that before until I found in the documentation of scrollContentsBy:



Calling this function in order to scroll programmatically is an error, use the scroll bars instead (e.g. by calling QScrollBar::setValue() directly).


So just made a good signal/slot system and called the QGraphicsView::horizontalScrollBar->setValue(value) with value being how much I moved the item and it works fine. :)

Sergex
25th November 2011, 14:52
Made some tests and although it scrolls the view contents fine, the value I am giving seems not to be precise. Does anyone have an idea of how I can calculate the amount of movement in the scene to the amount of what it would be if the scrollbar slider was moved?

Spitfire
25th November 2011, 15:13
Set your slider (the one that controlls the scrolling) min value to 0 and max value to 100 then:
viewScrollBar->setValue( viewScrollBar->maximum() * ( controlSlider->value() / 100.0f ) );should do the trick.

Sergex
25th November 2011, 16:10
Thanks, that does give me some ideas however I am not controlling the scrolling with a Scrollbar or slider, it is a Rectangular graphicsItem. When I zoom-in, the rectangular item shrinks exactly like the scrollbars of the view. So what I am doing is just hiding the scroll bars of the QGV and control the scrolling by moving the rectangular item horizontally. So I am having trouble in "mapping" when I move the rectItem, how much I moved this item should equivalently scroll the views by that amount.

I tried getting the values in scene coordinates, since my scene is the same size of my view's viewport,.. and try to get an equivalent number to set viewsScrollBar->setValue(value + dx). Being value the scrollBar's current value and dx the amount I need to move it.

Any idea how I can achieve this?? Thanks for the help!

Spitfire
25th November 2011, 16:55
I'm not sure if I understood what you're trying to do...
You have graphics item in the scene that controls graphics view scroll bars?
What I wrote previously still applies, you just get values from different place.

Assuming that the item you use to control has min and max bound and you can know them then it would be something like that:

double percent = controlItemCurrentX / controlItemMaxX; // one of the values has to be double/float otherwise it won't work
viewScrollBar->setValue( viewScrollBar->maximum() * percent );the idea is to get control item percentage position alongside its axis, then you know where along the scene axis viewport should be.

To make it more accurate you may need to factor in viewport size into the calculation.