Results 1 to 10 of 10

Thread: Redrawing a single row of a QwtPlotSpectrogram

  1. #1
    Join Date
    Nov 2009
    Posts
    39
    Thanks
    9
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Redrawing a single row of a QwtPlotSpectrogram

    I'm using the QwtPlotSpectrogram class to draw a spectrogram from a matrix of doubles. The matrix data is updating row-by-row and is updating at an extremely fast rate. Calling replot() works fine when my canvas is small, but when my canvas is large, replot() takes too long and can't keep up with the update rate of the canvas (i.e., plotting the updates is very jumpy and isn't smooth enought. Is there a way to selectively redraw parts of the canvas? For instance, if I have a canvas which is 1024x768 pixels, how could I redraw only the 1024 pixels in row N? I see there's a QPixmap object called paintCache in QwtPlotCanvas which seems like a good place to start looking, but I was wondering if anyone knew of an easy solution.

    Thanks in advance,
    MSUdom5

  2. #2
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,312
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    Better overload QwtSpectrogram::renderImage and store the image of the first render operation. Then shift the cached image and calculate the additional rows only.

    Uwe

  3. The following user says thank you to Uwe for this useful post:

    MSUdom5 (30th November 2009)

  4. #3
    Join Date
    Nov 2009
    Posts
    39
    Thanks
    9
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    Thanks Uwe. I'll give that a try.

  5. #4
    Join Date
    Nov 2009
    Posts
    39
    Thanks
    9
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    I'm trying to implement this without changing any of the core Qwt source, but I've hit a snag:

    How can I buffer the previous image? I can keep up with a QImage object "buffer_image" within my derived spectrogram class, but I can't change it in my overloaded renderImage since renderImage is a constant function. Is there any way I can get access to the currently drawn QImage from within QwtPlotSpectrogram? What would be the cleanest way to access (or store) the previously drawn image without changing any of the original Qwt source?

    Thanks,
    MSUdom5

  6. #5
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,312
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    How can I buffer the previous image? I can keep up with a QImage object "buffer_image" within my derived spectrogram class, but I can't change it in my overloaded renderImage since renderImage is a constant function.
    No, see: http://www.highprogrammer.com/alan/rants/mutable.html. Of course you can also do a const_cast for your this pointer.

    Uwe
    Last edited by Uwe; 1st December 2009 at 15:56. Reason: QUOTE tag fixed

  7. The following user says thank you to Uwe for this useful post:

    MSUdom5 (1st December 2009)

  8. #6
    Join Date
    Nov 2009
    Posts
    39
    Thanks
    9
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    Interesting, never used mutable before but it seems to work fine. However, I bet if my C++ professor were around, I'd probably get a slap on the hand...

  9. #7
    Join Date
    Nov 2009
    Posts
    39
    Thanks
    9
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    Got it working!! Very smooth scrolling animation now. Uwe, thanks so much for your help!

  10. #8
    Join Date
    Nov 2009
    Posts
    39
    Thanks
    9
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    Although I've achieved my original goal, I'm now looking to generate large plots quicker and more efficiently. How much of a change would be involved to use OpenGL to paint plots instead of QPainter? I'm assuming I'll need to subclass QwtPlot? Uwe, any advice/direction?

  11. #9
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,312
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    First of all I would optimize the existing solution and turn all paint caches off, because you have your own image cache:

    a) Spectrogram item
    Qt Code:
    1. spectrogram->setCachePolicy(QwtPlotRasterItem::NoCache);
    To copy to clipboard, switch view to plain text mode 

    b) Plot canvas

    Qt Code:
    1. plot->canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
    2. plot->canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
    To copy to clipboard, switch view to plain text mode 
    c) Qt ( only supported on X11 )

    Qt Code:
    1. plot->canvas()->setAttribute(Qt::WA_PaintOnScreen, true);
    To copy to clipboard, switch view to plain text mode 

    Another optimization on multicore systems is to render parts of the image parallel in several threads.

    Uwe

  12. #10
    Join Date
    Nov 2009
    Posts
    39
    Thanks
    9
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Redrawing a single row of a QwtPlotSpectrogram

    Thanks! I'd already applied a) (the default is NoCache I think). I just applied b), and it sped things up a little. I'm using Windows (unfortunately), so c) doesn't apply.

    For the most part, I'm getting the performance I need, so moving rendering to the GPU isn't absolutely necessary for me. My profiler says that most of the work is being done in qdrawhelper_p in some low-level math functions, so I don't think there's a higher level bottleneck. However, for a 1024x768 canvas, I'd like to be able to do 30 draws a second. Right now I can only get to ~20. (For smaller canvas, I have no problem with 30).

Similar Threads

  1. can a single statement work in signal/slot mechanism
    By salmanmanekia in forum Qt Programming
    Replies: 1
    Last Post: 8th August 2008, 08:24
  2. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13

Bookmarks

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.