Results 1 to 5 of 5

Thread: How to run a widget's PaintEvent on another QThread

  1. #1
    Join Date
    Jan 2015
    Posts
    35
    Thanks
    20
    Qt products
    Qt5
    Platforms
    MacOS X Windows

    Default How to run a widget's PaintEvent on another QThread

    Hi,

    I change the pictures on my app background with Qtimer by using opacity (like Blend transaction).
    It works well.

    void MyDesktop:: paintEvent (QPaintEvent * ) {

    QPainter BPainter1(this);
    myBPix = QPixmap(fileName1);
    BPainter1.setOpacity(1.0-_qBOpacity);
    BPainter1.drawPixmap(1,1,this->width(),this->height(),myBPix);

    QPainter Bpainter2(this);
    myBPix2 = QPixmap(fileName2);
    Bpainter2.setOpacity(_qBOpacity);
    Bpainter2.drawPixmap(1,1,this->width(),this->height(),myBPix2);

    }
    Then I also move labels with Qtimer when I pressed a key.
    Moving labels is ok but delay while background picture is changing.
    So I want to run background picture changing on another Qthread.
    To change picture opacity I use paintEvent on a widget.
    How can I run a widget's paintEvent from another Qthread?
    or Other Way?

    Thanks.
    Last edited by binary001; 2nd April 2015 at 17:28.

  2. #2
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to run a widget's PaintEvent on another QThread

    All GUI operations must be run from the main thread, so you cannot do that. However, why do reload the pixmaps from disk every time you repaint the widget? This is likely the main reason for the bad performance you get. You should preload the pixmaps, e.g. in the widget's constructor, and see if that improves the situation.

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

    binary001 (2nd April 2015)

  4. #3
    Join Date
    Jan 2015
    Posts
    35
    Thanks
    20
    Qt products
    Qt5
    Platforms
    MacOS X Windows

    Default Re: How to run a widget's PaintEvent on another QThread

    Thanks for your replay.

    I want to use and reload so many pictures (just like wallpaper transaction) from disk. If all pictures are preloaded, app size is very big.
    Now I try to use setGraphicsEffect from QThread.

  5. #4
    Join Date
    Sep 2009
    Location
    Wroclaw, Poland
    Posts
    1,394
    Thanked 342 Times in 324 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: How to run a widget's PaintEvent on another QThread

    If all pictures are preloaded, app size is very big.
    yeye_olive means that you should load them to memory when your app is running, not include them into app.exe.
    Qt Code:
    1. Now I try to use setGraphicsEffect from QThread.
    To copy to clipboard, switch view to plain text mode 
    That probably won't work - all GUI related operations have to be used from the main thread, as already mentioned.

  6. The following user says thank you to stampede for this useful post:

    binary001 (2nd April 2015)

  7. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to run a widget's PaintEvent on another QThread

    If all pictures are preloaded
    You only need to have two pictures loaded at any time - the one you are fading in, and the one you are fading out. In your timeout handler, when the opacity reaches 0 (or 1, whatever), just emit a signal or call a method to load the next image (and swap the pixmaps so that the one that was faded in is now the one to fade out):

    Qt Code:
    1. pixmap1 = pixmap2;
    2. pixmap2.load( nextFileName );
    To copy to clipboard, switch view to plain text mode 

    It is not necessary to have two QPainter instances in the paint event. Just change the opacity on a single QPainter instance between drawing the two pixmaps.

    The only thing you might want to preload is the list of picture file names. And you don't really even need to do that - you can create a QDirIterator as a member of your class, and simply call QDirIterator::next():

    Qt Code:
    1. pixmap1 = pixmap2;
    2. if ( myDirIterator.hasNext() == false )
    3. myDirIterator = QDirIterator( path-to-picture-directory ); // restart from the beginning
    4. pixmap2.load( myDirIterator.next() );
    To copy to clipboard, switch view to plain text mode 

    This code swaps the pixmaps, then checks to see if there are any files remaining in the list. If there are still files remaining, it loads the next one. If not, it resets the iterator back to the beginning and then loads the first one.
    Last edited by d_stranz; 4th April 2015 at 04:30.

Similar Threads

  1. Replies: 1
    Last Post: 9th May 2012, 08:58
  2. Replies: 1
    Last Post: 11th March 2011, 19:34
  3. How to paint a widget outside paintEvent()
    By wesley in forum Qt Programming
    Replies: 10
    Last Post: 27th February 2008, 03:19
  4. painting a widget outside a paintEvent
    By jayw710 in forum Qt Programming
    Replies: 1
    Last Post: 25th June 2007, 23:18
  5. New thread to handle paintEvent
    By bitChanger in forum Qt Programming
    Replies: 1
    Last Post: 9th March 2006, 21:41

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.