View Full Version : How do I get viewing area notifications on QGraphicsView?

31st March 2011, 21:02
Hello, everyone,

This is my first post to QtCentre, so hopefully, I'm in the right place. I've been working with Qt for a couple of months, and it's the most fun I've had at work in a very, very long time.

The issue I'm struggling with is how to get notified when the viewing area of QGraphicsView changes. I would expect that this is a common need and am surprised that it doesn't seem to be as easy as everything else in Qt.

The QGraphicsView has panning and scroll bars enabled and zooming as well, so I need to be notified whenever the viewing area changes (not the scene content...just the viewing area). Additionally, since the viewing area changes when scroll bars appear, I need to know that as well.

Thank you,

31st March 2011, 22:59
Why do you need such notification?

2nd April 2011, 01:09
I have an application with a type "heads-up" mechanism where items in the graphics scene need to stay positioned within the view. The heads-up items are graphics scene items, and that's how I need them to be. Essentially, whenever the viewing area changes, I need to reposition/resize the heads-up items to always remain on view in a fixed location. I've experimented with a variety of other mechanisms, and the current approach that I'm working with seems to be the best choice so far.

I have the scaling working, but I need to fix panning, which requires that I know when the viewing area has been panned.


And yes, I realize this breaks the concept of being able to use multiple views on a single scene. While that's unfortunate, it's not terribly important for this application, and the sacrifice is worth it.

2nd April 2011, 08:44
Panning is simple as you can connect to scroll bar's valueChanged() signals. But in general what you're doing violates the model-view separation of graphics view, your HUD items shouldn't be items, most probably - they are obviously tied to the viewport and not to the scene. Why do you need them to be items?

2nd April 2011, 13:00
The problem description is a little unclear, but a look at QGraphicsView.drawForeground() might be worthwhile here.

2nd April 2011, 13:13
drawForeground draws in scene coordinates and not view coordinates, I'd suggest having another scene mapped directly to the size of the view's viewport and overpainting this second scene on the viewport if those HUD items really need to be items.

5th April 2011, 01:49
Thank you, everyone, but those are all suggestions that I'd tried, except for tying to the changed signal from the scroll bars. I independently figured that out, and I have what I need, so my actual problem is solved.

However, to clarify...as I said in my original post, I understand that manipulating the scene from the view violates the model/view separation. That's a disappointing side-effect, but we can live with that in this application. The benefit outweighs the loss.

The items need to be items rather than overpainting in the foreground layer because of the way that our drawing application works (and this is a legacy application being ported to Qt, not a new application). What I actually have are layers in schematics where some layers are zoomable, but others are fixed and always on-top of everything else. The fixed layers contain exactly the same kinds of objects with exactly the same features as in the zoomable layers. They're selectable, movable, and identical in every way to the items that I already have working, so it's extremely undesirable to write custom code for the ~80 different variations of objects when the variants on QGraphicsItem already handle *everything* that we need.

I tried layering a separate view/scene over the top of the first one; that was one of my first attempts, but events weren't propagating to the lower scene. I don't think I got as far as testing clicks, but the mouse wheel events when to the fixed scene rather than to the zoomable layer. I assumed that I'd have the same problem with clicks and keyboard events. It's possible that I could've solved this by manipulating the events, but I'm too inexperienced with Qt's event handling to do that. (I tried, however. There's a limit to how much time I'll spend on something before moving to a different technique.) Everything I could come up with required manipulating/forwarding events in ways that I didn't think were desirable.

This isn't exactly a heads-up display, but that's a very good analogy, so that's the analogy I used in my description. Even if I've not been clear enough in my description, it's *very* clear that Qt falls short in this particular circumstance. Googling this issue brings up the same issue repeatedly; everyone who wants a heads-up display wants to be able to used QGraphicsItems for the fixed elements, and mostly likely for many of the same reasons that I do. drawForeground is completely inadequate for much beyond a very simple, non-interactive overlay.

Most everything I've done in Qt has been fantastic, but I hope that the developers are reading this and will consider an addition to the QGraphicsView/QGraphicsScene infrastructure that allows either layering multiple scenes (which I'm sure is not easy) with intuitive event propagation, or allowing the use of QGraphicsItems in the foreground and/or background layers and that optionally use view coordinates instead of scene coordinates. This is a common need, and the feature is just plain missing.

Thanks for the advice and help; I'm sure I'll be back with more questions in the future, and I appreciate it.

5th April 2011, 10:00
Have you tried to set the flag QGraphicsItem::ItemIgnoresTransformations (http://doc.trolltech.com/latest/qgraphicsitem.html#GraphicsItemFlag-enum) on your overlay schematics?


5th April 2011, 10:19
Have you tried to set the flag QGraphicsItem::ItemIgnoresTransformations (http://doc.trolltech.com/latest/qgraphicsitem.html#GraphicsItemFlag-enum) on your overlay schematics?


That'll take care of rotations and scalings, but sadly not translations. Items will stiil move with the view when the scrollbars are manipulated.