[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