Results 1 to 4 of 4

Thread: GraphicsView: how to avoid animated background when animating sceneRect

  1. #1

    Default GraphicsView: how to avoid animated background when animating sceneRect


    I'm using the GraphicsView framework to realize a custom 2D GUI. I created the different menu screens in Photoshop, and separately exported the background image on the one hand, and transparent (PNG) images that I place in the different menu screens on the other hand. Each of my menu screen is realized by a class I created, which extends QGraphicsObject. In the QGraphicsView, where I setup the QGraphicsScene, I call
    Qt Code:
    1. QGraphicsScene::setBackgroundBrush()
    To copy to clipboard, switch view to plain text mode 
    on it to set the background image.

    Since I want menu transitions in the "swipe left/right" fashion (i.e. one menu flies out of the view, e.g. to the left, and the next menu flies into the view from the right), I decided to arrange all the menus (QGraphicsObjects) spatially in the QGraphicsScene next to each other. Using the State machine framework and animations framework, I have one state per menu screen, and I'm assigning the QGraphicsView's sceneRect property to a QRectF for each state independently.

    Generally this approach works, and I get smooth menu-to-menu transitions. However, the transitions do not look right. What I want (expect) is that the background image always stays static, "as it is" (regardless that sceneRect is animated), i.e. I'd expect that only the transparent parts of my menu screens are "flying" in/out of the view from the left/right. However, unforunately the background itself does also move, i.e. it is as if QT has taken a screenshot of the view right at the start, and one at the end of the animation, and then animate between the two screenshots.

    Is there a way I can force the background to be completely static anyways?


  2. #2
    Join Date
    Oct 2009
    Thanked 10 Times in 10 Posts
    Qt products
    Unix/X11 Windows

    Default Re: GraphicsView: how to avoid animated background when animating sceneRect

    i cant complete visualize you problem. maybe some screenshot or even better the minimal source code who reproduce your problem.

    meanwile you maybe try some one of this options
    - draw background in the view not the scene. set QGrapicsView::setBackgroundBrush(),
    - reimplement QGraphicsView::drawBackground() this provide more control over how painting the background

  3. #3
    Join Date
    Jan 2008
    Alameda, CA, USA
    Thanked 808 Times in 797 Posts
    Qt products
    Windows Android

    Default Re: GraphicsView: how to avoid animated background when animating sceneRect

    You might also try one of the caching options on the QGraphicsItem that holds the images. This was vital in my app to allow smooth rubber banding over a complex background graphic. Using caching on the graphic meant that it would only be physically redrawn when the content or size changed; all the rest of the time it was simply blitted from the cache, with no noticeable flicker at all.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  4. #4

    Default Re: GraphicsView: how to avoid animated background when animating sceneRect

    Hi. Generally what I want to achieve is that the drawn background image sticks to the "animated camera" (if you agree on calling the animation of QGraphicsView's sceneRect as animating a camera view).
    A visualization of my problem:
    Below you see, in this order, the first menu screen, the second menu screen, and the bad transition I get from the first to the second menu screen. It looks bad because in the transition the background is also moving, even though it really shouldn't. It seems that QT actually replicates/tiles the background image over the complete scene.

    Changing to set the backgroundBrush on the QGraphicsView rather than the QGraphicsScene did unfortunately not have any effect (problem remains the same).

    Regarding caching:
    In my QGraphicsview I use:
    Qt Code:
    1. setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    2. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    3. setViewportUpdateMode(FullViewportUpdate);
    4. setCacheMode(CacheBackground);
    5. setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
    To copy to clipboard, switch view to plain text mode 
    Disabling the CacheBackground does not fix the problem either, but decreases performance significantly.

    Regarding the items I place in the scene (i.e. the menu screens), I use
    Qt Code:
    1. setCacheMode(QGraphicsItem::DeviceCoordinateCache)
    To copy to clipboard, switch view to plain text mode 
    I'm quite reluctant to touch (override) the drawBackground(), basically because I've already tried before (when I was tinkering how to make sure the view always scales with my viewport, which I solved via fitInView(scene()->sceneRect(), Qt::IgnoreAspectRatio) at last). And I did not have much success in understanding what the parameters are, or, basically how to draw the background correctly.

    Added after 28 minutes:

    This (click me) got me close to the solution of my problem. However, the background image is not correctly scaled. My current solution to this scaling problem is that inside the drawBackground method, I replace the drawPixmap() call with
    Qt Code:
    1. painter->drawPixmap(old.mapRect(rect), backgroundImage.scaled(viewport()->width(), viewport()->height()), old.mapRect(rect));
    To copy to clipboard, switch view to plain text mode 
    While this works, I discovered that drawBackground() is called ca. 30 times during a transition from one screen to the next, and once I'm full screen (and at high resolution) this causes harsh performance drops. Why does QT have to redraw the background constantly during a transition? How can I avoid that (Note: background cache is already enabled, otherwise drawBackground would be called ALL the time)? I somehow need to be able to paint the rescaled background into some kind of buffer which does not require to be changed, even when the sceneRect changes...

    Some detail information about my case:
    The background image has a dimension of 1920x1080 pixels. I also set a rectangle (0, 0, 1920, 1080) on myQscene->setSceneRect(..), otherwise the view would show all the menu screens at once (like a bird's eye view), rather than just one screen at a time. My application starts in WIndowed mode, but via a keyboard shortcut I can also go into full-screen mode.
    Last edited by NameZero912; 19th August 2012 at 11:05.

Similar Threads

  1. QGraphicsscene.sceneRect on Windows platform
    By sanku3 in forum Qt Programming
    Replies: 0
    Last Post: 26th September 2011, 08:12
  2. bad sceneRect with scaled text
    By koosh in forum Qt Programming
    Replies: 14
    Last Post: 10th July 2008, 19:29
  3. put image on scenerect
    By dreamer in forum Qt Programming
    Replies: 3
    Last Post: 13th May 2008, 06:55
  4. GraphicsView update background
    By maverick_pol in forum Qt Programming
    Replies: 9
    Last Post: 27th February 2008, 19:25
  5. QGraphicsScene: evolution of sceneRect
    By Pieter from Belgium in forum Qt Programming
    Replies: 2
    Last Post: 10th November 2006, 15:11

Tags for this Thread


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.