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

Samuel Rødal samuel.rodal at Nokia.com
Fri Jan 22 14:09:23 CET 2010


ext Thomas Fjellstrom wrote:
> On Fri January 22 2010, Thomas Fjellstrom wrote:
>> On Fri January 22 2010, you wrote:
>>> ext Thomas Fjellstrom wrote:
>>>> I'm trying to get a few items to completely ignore the scene's
>>>> current translation and transforms. That is, I'd like the item to
>>>> stay at a fixed position in the view, regardless of any zooming, or
>>>> movement in the view itself. And do that without it looking like I'm
>>>> manually moving the item with the view (ie: it lagging slightly
>>>> behind the scrolling).
>>>>
>>>> I've played with the QGraphicsItem::ItemIgnoresTransformations flag,
>>>> it definitely doesn't ignore translations in the scene at all, and it
>>>> seems to mess up the "y rotate" animation I added to a couple items.
>>>> It looks like its shifting the item's coordinates around a little. I
>>>> use: setTransformOriginPoint(size().width()/2, size().height()/2); to
>>>> set the transform point to the centre of the item, so my item
>>>> (without the ignore flag) flips around the y axis (centre of the
>>>> item) nicely. With the ignore flag, it flips around the right hand
>>>> edge of the item, and seems to shift its x position as it flips.
>>>>
>>>> I'm using Qt 4.6.0 (from qt.nokia.com, not a distro package), on
>>>> linux 2.6.32 + KDE 4.3.4.
>>>>
>>>> Is there any way to get the behaviour I'm looking for? Thank you.
>>> Have you considered not transforming the view, and instead making all
>>> the transformable item children of a top-level invisible graphics item?
>>> Then you could transform all the child items by transforming the
>>> top-level, leaving the non-transformable items as they were.
>> How would that mess up scrolling the items in that top level item? I
>>  assume I'd have to do it manually myself now?
>>
>> Basically I have a 2D game board with each square as a separate QGWidget,
>> with a large enough board it easily becomes larger than the view (even on
>>  my 24" 1920x1080 LCD), and will need to scroll the items around. I also
>>  want to enable scaling the board up and down so all the items can be
>>  seen at once, or only a small subset (but much larger). Along with that
>>  I plan to make the entire gui of the game be widgets in the QGV. Right
>>  now I have my login, register, and "game request" dialogs as themed
>>  QGWidgets, they work fairly well, I just want to clean up the user
>>  interaction a little. I also intend to make the game status information
>>  be a horizontal translucent bar at the top of the view, as well as
>>  moving my current "chat" and "userlist" interface inside the view as
>>  well, but all of them will need to have a static transform and
>>  translation relative to the view. I don't want any of the UI to zoom or
>>  move with the board.
>>
>> Given your email address, I can only assume that what I want probably
>>  isn't possible without making some more custom widgets. The only
>>  solution I've come up with so far (based on your suggestion) is to make
>>  the board a fancier widget, that handles its own scrolling and zooming,
>>  probably utilizing the animation framework to handle smooth, natural
>>  feeling scrolling (and zooming).
>>
>> Luckily the only bits I'll want to zoom, or translate are inside my
>> "GameBoard" widget, so it may not require many changes, other than maybe
>>  a new "ScrollZoomItem" that handles scrolling and zooming one or more
>>  subwidgets, including scrollbars...
>>
>> But it would be nice if Qt supported something like this a little more
>> directly.
>>
>> But then, maybe I'm just lazy.
> 
> The fun part will probably be getting the board to properly accept input 
> (each square on the board accepts mouse clicks, and "grow" on hover), as 
> well as scroll and zoom.

I'm not sure why scrolling and zooming will be a problem. 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.

--
Samuel






More information about the Qt-interest-old mailing list