0

I created QPropertyAnimation and connected it to my SonogramWidget that scroll a long picture vertically on animation events. The 'long picture' is composed of 100 pre-calculated QPixmap objects 1024x128 placed one after another vertically. They displayed in SonogramWidget::paintEvent() with QPainter. Drawing procedure paint not all QPixmap at once, but only visible of them, considering widget height and current vertical offset. CPU is almost free, because QPixmap is a fastest way to display a picture. There is no big calculations during scrolling, because all the 100 QPixmaps are pre-calculated and stored in memory.

I see strange effect: pulsating movement: 2 times a second the entire image slightly speed-up and moves up by 1..2 pixels faster than usual motion. The same effect when i replace Qt Animation Framework with single 60 fps QTimer and scroll the image in its SLOT.

Video: http://www.youtube.com/watch?v=KRk_LNd7EBg#t=8 (watch from 00:08; My firefox adds more chopping to video playing itself, google chrome plays the video much better).

I see the same effect for my Linux and Windows build.

SOLUTION i figured out the issue: the "chopping" was not a bug, it was a feature! It is a feature of integer-number calculations, so sometimes we had to have different numbers for animations, like: 16,16,16,16,16,16,17,16,16,16,16,16,17,....

pavelkolodin
  • 2,859
  • 3
  • 31
  • 74
  • What is your CPU load saying? The scrolling gets slower the more 'white' is visible. Since it should not make a difference for QPainter whether a pixel to draw is white or black, it must be something with your calcalations. If your machine is close to its limit, I'd expect strange output artefacts like this. Or is this 'getting slower' an optical illusion? Not sure. – Greenflow Aug 30 '13 at 09:07
  • All the QPixmaps are pre-calculated and stored in memory. No calculations during scrolling. With only-black pixels the entire image is less contrast and we don't notice the described effect. – pavelkolodin Aug 30 '13 at 09:09
  • I have no idea, so it is pure guessing. But sometimes even this helps. :-) So, is it possible for you to put all in one pixmap? Only temporary? Just to rule out that somehow the 100 vertical QPixmaps interact strangely? – Greenflow Aug 30 '13 at 09:41
  • Even though the QPixmap images are pre-calculated, you're copying the visible ones in the paintEvent of SonogramWidget, aren't you? If so, can you post that code? – TheDarkKnight Aug 30 '13 at 09:42
  • @Greenflow guessing - is what i need! I tried that and as i remember, i saw the same effect, so i rejected that strategy. – pavelkolodin Aug 30 '13 at 09:47
  • @Merlin069 current code has lots of details, so i am afraid it would be hard to read it. I will try to create separate project only to reproduce this described effect later. – pavelkolodin Aug 30 '13 at 09:48
  • Note that the paint function should be as optimal as possible and only deal with drawing to the screen. If this is not the case in your project, it could explain the issues you're seeing. – TheDarkKnight Aug 30 '13 at 09:51
  • Painting and updating is at some point always event loop triggered. I **guess** that there is some other event, which is triggered in a regular interval and which slightly changes the timing of your paint routine. – Greenflow Aug 30 '13 at 09:52
  • @Greenflow so, your guess is that QPropertyAnimation runs on the same event loop that is used for all my events processing and sometimes that event loop is too busy to provide needed 'tick' to QPropertyAnimation? Can i create independent event loop special for QPropertyAnimation? – pavelkolodin Aug 30 '13 at 10:44
  • Maybe it is nonsense what I say. But I would not pin this on QPropertyAnimation. At some point your QPixmap must be painted on your widget. This is triggered by a paintEvent. If now this paintEvent does not come regularly, e.g. every x ms it comes a few ms later, because something else in the main event loop delayed its execution. I don't know big or how small this delay must be to be visible. But for some things our eyes are annoyingly sensitive. Merlin seem to have more experience in this field. – Greenflow Aug 30 '13 at 11:01
  • @Greenflow o, i see. paintEvent() is called in main loop of QApplication and i cannot move paintEvent() calling to another independent 'main loop'? – pavelkolodin Aug 30 '13 at 11:08
  • I don't think this is possible. At least I don't know how. Creating a new event loop is easy, but I don't think you can use it to deliver paintEvents instead of the main event loop. Here is a good description of the Qt event system: http://doc.qt.digia.com/qq/qq11-events.html. And be careful with my attempted explanation of your problem. The general idea is certainly not wrong, but the effect might be far to small to be the real cause for your problem. – Greenflow Aug 30 '13 at 11:24
  • Sorry I'm late replying - I only just got notified of comments. While you can't move any paint related code to another thread, you can move all other code. Again, without seeing your code, it's difficult to do anything but make generalised suggestions. However, if you've got any code running on the main thread that isn't doing rendering, you could try moving that to another QThread, though ensure you use QThread properly: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/ – TheDarkKnight Sep 03 '13 at 15:21
  • @Merlin069 i figured out the issue: the "chopping" was not a bug, it was a feature! :) It is a feature of integer-number calculations, so sometimes we had to have different numbers for animations, like: 16,16,16,16,16,16,`17`,16,16,16,16,16,`17`,.... – pavelkolodin Sep 03 '13 at 15:28
  • Ha, I'm glad to hear it. As I said all along, Qt can be great, when used properly ;O) – TheDarkKnight Sep 03 '13 at 15:40

1 Answers1

0

In the paintEvent add the following assert:

Q_ASSERT(m_animation->currentValue() == m_animatedPropertyValue);

If it triggers, then you know you must use currentValue() instead of the property value. This might be the case. Let me know.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313