[Qt-interest] QGraphicsItem ignore scene translation/transform?

Thomas Fjellstrom tfjellstrom at shaw.ca
Fri Jan 22 17:11:21 CET 2010


On Fri January 22 2010, Samuel Rødal wrote:
> ext Thomas Fjellstrom wrote:
> > On Fri January 22 2010, Samuel Rødal wrote:
> >> ext Thomas Fjellstrom wrote:
> >>> On Fri January 22 2010, Samuel Rødal wrote:
> >>>> Basically the
> >>>> top-level item is just an invisible item whose bounding rect is the
> >>>> same as the combined bounding rect of the child items (game
> >>>> squares). Whenever you earlier scaled / scrolled the view itself
> >>>> you'd now do the same with the top level item. You might wish to use
> >>>> QGraphicsScene::setSceneRect() to control which part of the scene
> >>>> should be mapped to the view at any time.
> >>>>
> >>>> I don't think this way of doing things should be significantly
> >>>> harder than changing the view transformation.
> >>>
> >>> But how to actually handle the events is something else. Right now
> >>> the child widgets all accept mouse events, which means the parent
> >>> widget doesn't get them, so it can't know when a person is trying to
> >>> scroll or zoom.
> >>>
> >>> I'm not sure how to have both, selecting the game elements, AND
> >>> letting the game board accept events to handle scrolling and zooming.
> >>
> >> Not sure I understand from where you're currently triggering scrolling
> >> and zooming. Does each game square currently tell the view it needs to
> >> scroll or zoom? If so, can't you keep the current design but instead
> >> tell the invisible game board item to scroll / zoom?
> >
> > Sorry if I wasn't clear enough before.
> >
> > Right now the scrolling happens due to the QGV's own scroll bar.
> > Zooming would have (I haven't implemented it yet) been done with the
> > scroll wheel for now (and touch events in the future).
> >
> > Moving to keeping the scene's translation and transformation static
> > would mean disabling the view's scroll bar, and either implementing my
> > own, or scrolling by clicking anywhere on the "game board" and dragging
> > the board around (which is how it _will_ work on touch based devices).
> 
> Ah, that will be a problem yes. You'd have to set the scene rect to the
> bounding rect of the game board, but that means whenever graphicsview
> scrolls your non-transformable items will still be transformed. In that
> case I guess you can't avoid having to dynamically change the
> transformation of these items to have them match the current view (and
> you might as well go back to transforming the view directly in this case
> like you're already doing). Maybe there's a way to keep the item
> transformations and the view transformation in sync while avoiding any
> visual lag.

I'm currently leaning towards disabling the view's scrollbars, and not using 
scene global translation or transformation. And having the Game Board widget 
handle scaling and scrolling with a sub item/widget. Possibly even going so 
far as to make the sub widget render and handle all the input for all 
squares, instead of using sub items. But I'm probably missing something that 
might cause that to not work.

So basically it would work like this:

ScrollZoomAreaItem contains my GameBoard item which contains zero or more 
child widgets that get translated and transformed. The ScrollZoomAreaItem 
widget will render any fancy scroll+zoom indicators (ie: some kind of scroll 
bars, and zoom level indication), which control the child's transform and 
translation matrix. The issue still seems to be that the GameBoard will want 
to accept input, and so will the ScrollZoomAreaItem. As I said before, this 
might be possible to "fix" by cancelling any action on the GameBoard if any 
movement any greater than some threshold is detected, and pass the events 
down to the ScrollZoomAreaItem.. If possible.

> Another option would be to not have these items be graphics items, but
> just draw them at static positions in QGraphicsView::drawForeground().
> Then override graphics view's event handlers and only pass them on to
> the QGraphicsView base class if the event is not meant for any of the
> foreground "items".
> 

Hmm, how would one go about doing that when future items will be fairly 
complex? Like an instant messaging interface, and a list of users in various 
"groups" you subscribe to. They absolutely need to accept input, and I'd 
also like for them to animate fairly slickly (very easy to do with 4.6!).

The current user list and chat interface is really ugly, and sits in 
QDockWidgets. I really want to move them into the GraphicsView, and be 
themed along with the rest of the GraphicsView items I have (I wrote a set 
of Theme and Svg classes that are eerily similar to Plasma's Theme and Svg 
classes, but they work very well so I don't feel so bad about riping plasma 
off ;) ).

-- 
Thomas Fjellstrom
tfjellstrom at shaw.ca




More information about the Qt-interest-old mailing list