Preventing flicker of moving images
-
Initial warning: I'm using the PyQt bindings, but I think this question is sufficiently general that you guys can help even if you're not familiar with PyQt, and this forum seems much more active than the Language bindings forum.
I'm writing a program which involves moving images across the screen at a reasonable speed. My first approach was just to use QLabels with an associated image, and call move() in timerEvent. However, I noticed that this resulted in quite a lot of flicker/tearing.
I posted a question about it on StackOverflow "here":http://stackoverflow.com/questions/5112110/preventing-blurring-of-fast-moving-objects-on-the-screen (includes a link to a toy program that exhibits the problem). Someone told me that it could be fixed with double-buffering. I did lots of reading and googling on this, and then got a bit confused when I read this in the Qt documentation: "Since Qt 4.0, QWidget automatically double-buffers its painting, so there is no need to write double-buffering code in paintEvent() to avoid flicker".
From here, I really have no clue how to proceed. I thought that maybe if I tossed out the Qlabels and used QGraphicsItemAnimations I could fix the problem, but doing this seemed to result in at best a slight improvement. "Here's":http://dpaste.com/hold/446403/ a paste of my attempted use of QGraphicsItemAnimation (the code is horrible and hacked together from example code in the Qt documentation - it's just meant to be a short demonstration); it takes the path to an image file as an argument, and swishes that image across the screen a few times.
Can anyone recommend what strategy to take here? Am I using the wrong kind of widget? Do I need to somehow implement double buffering myself? This problem has been plaguing me for a long time, and I'm really at my wits' end, so I'd be tremendously grateful for any help. I've put dozens of hours into this project, and really don't want to have to start again with a different language or framework.
-
Only two hints: Try QPropertyAnimation and drawing to QGLWidget. Hope it helps.
-
Did you try to force display updates ?
I had the problem in my graphicsview, I display there a graphs that updates on a slider movement somewhere else in the GUI.
I remember I sometime had to do some tricks to get it smooth, it seems Qt only refresh a few time if you don't force it. try something similar to "graphicsview->Viewport()->update().Then setting QGLWidget as the viewport also has best rendering speed.
-
[quote author="unclewerner" date="1300355917"]Only two hints: Try QPropertyAnimation and drawing to QGLWidget. Hope it helps.[/quote]
I just tried using QPropertyAnimation and I still saw about the same amount of flickering and tearing. That was just on a regular old QLabel widget with a pixmap though. Should I be using it in conjunction with QGraphicsItems or something? I'm wondering how that's different from QGraphicsItemAnimation.About QGLWidget, I just tried using one of these as my viewport, and for some reason it looked even worse. I'm wondering to what degree, if any, this is hardware/OS/driver/whatever dependent? I'm on Ubuntu, and I'm wondering if it has weaker support for OpenGL? (I'm really not familiar with lower-levelish stuff, so that may be a stupid question)
[quote author="ness522" date="1300359025"]Did you try to force display updates ?
I had the problem in my graphicsview, I display there a graphs that updates on a slider movement somewhere else in the GUI.
I remember I sometime had to do some tricks to get it smooth, it seems Qt only refresh a few time if you don't force it. try something similar to "graphicsview->Viewport()->update().[/quote]
I think I'm able to control this through setUpdateInterval on the QTimeLine I'm using to control my animations. I've tried following the conventional wisdom of having an update interval of ~17 ms to match monitor refresh rates.Thank you guys so much for the tips. At this point, I'm happy to have anything at all to go on.