Results 1 to 16 of 16

Thread: How to display QPaint Images from other Threads

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    May 2011
    Posts
    16
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60

    Default How to display QPaint Images from other Threads

    Hi,
    I am using 2 threads in my program. 1 is GUI thread and other one is created from main application. I am getting frames in other thread and painting and displaying Images in main thread.

    After getting frames from other thread I am calling main thread paint function to paint on the widget. Here I am facing problem. I am getting 3 errors

    1. "QPixmap: It is not safe to use pixmaps outside the GUI thread"
    2. "QPainter::begin: Paint device returned engine == 0, type: 2"
    3. "QPainter::end: Painter not active, aborted"

    Here is my sudo code
    connect(thr, SIGNAL(sDisplayOnWidget()), this, SLOT(convertImg2Pix()))
    void frameThread::run() {
    mPlayer.loadVideo("/tmp/stream.bin");
    while(1) {
    mPlayer.loadVideoGetFrame();
    printf("we r in thread func \n");
    emit sDisplayOnWidget();
    }
    }
    convertImg2Pix() {
    p = QPixmap(img.size());
    QPainter painter;
    painter.begin(&p);
    painter.drawImage(0,0,img);
    painter.end();
    mLabelWidget->setPixmap(p);
    }
    please help me to get out of this problem.

    Thanks in advance...
    VijayQt

  2. #2
    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 display QPaint Images from other Threads

    QPixmap belongs to QtGui module, it's not safe to use it in threads other than gui. If you need to draw in other thread, use QImage and then send the result for display to gui thread.

  3. #3
    Join Date
    May 2011
    Posts
    16
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60

    Default Re: How to display QPaint Images from other Threads

    Thanks for your quick reply... I am doing QPixmap in main thread only.

    in my above code "convertImg2Pix()" function is in gui thread.
    VijayQt

  4. #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 display QPaint Images from other Threads

    Are you sure about that ? This warning says different.
    Add this debug code in both methods:
    Qt Code:
    1. qDebug() << /*method name here*/ << QThread::currentThread();
    To copy to clipboard, switch view to plain text mode 
    in my above code "convertImg2Pix()" function is in gui thread
    If it is, then maybe you are using QPixmaps somewhere else in your second thread code.

  5. #5
    Join Date
    May 2011
    Posts
    16
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60

    Default Re: How to display QPaint Images from other Threads

    Its not calling SLOT . Its always in the while loop and printing non-gui thread id .
    Non GUI thread frameThread(0x9ef78a8)
    why its not calling SLOT function?? Please guide me.
    VijayQt

  6. #6
    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 display QPaint Images from other Threads

    It's some kind of video player, so I think you should consider the video file fps, setup a QTimer in order to query frames in regular intervals and send them to display.
    Now it looks like you want to play the video as fast as possible, it's definitely not the way to go.
    Something like this (a pseudo-code):
    Qt Code:
    1. void VideoThread::run(){
    2. player.loadVideo("video file path");
    3. //...
    4. if( fps > 0 ){ // video fps
    5. timer.setInterval( 1000.0 / fps ); //
    6. connect(timer, SIGNAL(timeout()), this, SLOT(grabFrame()));
    7. timer.start();
    8. } else{
    9. // some kind of error handling
    10. }
    11. }
    12.  
    13. void VideoThread::grabFrame(){
    14. QImage img = player.getFrame();
    15. emit newFrame(img); // signal connected to some object from the gui thread, with Qt::QueuedConnection
    16. }
    17.  
    18. //...
    19.  
    20. void MainGui::frameCallback( const QImage& img ){
    21. qDebug() << "got frame";
    22. QPixmap p = /*img to pixmap*/;
    23. displayWidget->setPixmap(p);
    24. }
    To copy to clipboard, switch view to plain text mode 
    I think you can work on the details yourself.

  7. #7
    Join Date
    Aug 2008
    Posts
    45
    Thanks
    1
    Thanked 6 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to display QPaint Images from other Threads

    Do your main thread have event loop running? It will not call the convertImg2Pix() slot if it is not running.
    Last edited by joyer83; 2nd June 2011 at 17:23.

  8. #8
    Join Date
    May 2011
    Posts
    16
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60

    Default Re: How to display QPaint Images from other Threads

    Your guess is correct... I am working on video frames displaying on widget.

    void VideoThread::grabFrame(){
    QImage img = player.getFrame();
    emit newFrame(img); // signal connected to some object from the gui thread, with Qt::QueuedConnection
    }
    I can not emit from here because this peace of code is belong to MainGUI. What I am doing here is
    while(1) {
    gPlayer->nextFrame();
    QImage img = gPlayer->displayFrame();
    emit sDisplayOnWidget(img);
    qDebug() << "Non GUI thread" << QThread::currentThread();
    msleep(400);
    }
    but it's not emiting signal. what I am doing is wrong way or am I missing some thing??

    what is event loop??? I am using connect call to emit signal from other thread and slot to render the image.
    I don't know what it is??... Please can you give sudo code to run event loop.
    VijayQt

  9. #9
    Join Date
    Aug 2008
    Posts
    45
    Thanks
    1
    Thanked 6 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: How to display QPaint Images from other Threads

    The event loop is what calls the slots. Read Qt's documentation to find out more.
    The main event loop is started with QCoreApplication::exec();

    Try running your application inside a debugger, pause execution and check if main thread's call stack contains the exec() call.

    EDIT: Also do check that the object which contains the convertImg2Pix()-slot is living in main thread. You can get the object's thread with method QObject::thread().

    You should also check that the connect() call successes, like this:
    Qt Code:
    1. bool ok = connect( ... );
    2. Q_ASSERT( ok );
    To copy to clipboard, switch view to plain text mode 
    Last edited by joyer83; 2nd June 2011 at 17:46.

  10. #10
    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 display QPaint Images from other Threads

    If you can use gui, you can be sure there is an event loop running.
    I can not emit from here because this peace of code is belong to MainGUI
    This piece of code does not belong to anything, it's just a pseudo-code, you've asked about advice and here it is - I suggest you to setup a timer to grab frames. Don't forget to call "exec()" in your thread's run() method as well.

  11. #11
    Join Date
    May 2011
    Posts
    16
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60

    Default Re: How to display QPaint Images from other Threads

    Hi Stampede,
    I am talking about my code, not your pseudo-code. In comment#8 I pasted my code and that is from MainGUI.

    void thread::run() {
    while(1) {
    gPlayer->nextFrame(); // This function belong to MainGUI thread
    QImage img = gPlayer->displayFrame(); // This function belong to Main GUI thread
    emit sDisplayOnWidget(img); // from here I am calling SLOT function which is there in again MainGUI thread
    qDebug() << "Non GUI thread" << QThread::currentThread();
    msleep(400);
    }
    }

    Please let me know whether this is correct way of doing or not???

    If it is correct it's not uploading frame on the Label Widget...
    VijayQt

Similar Threads

  1. How to display DDS images?
    By jamsession in forum Qt Programming
    Replies: 5
    Last Post: 12th June 2013, 22:18
  2. Display images and move them
    By AL in forum Qt Programming
    Replies: 5
    Last Post: 11th February 2010, 17:49
  3. How do I display a list of images?
    By Morea in forum Qt Programming
    Replies: 2
    Last Post: 23rd November 2007, 08:49
  4. Is there any way to synchronize the display of images
    By kiransu123 in forum General Programming
    Replies: 2
    Last Post: 17th March 2007, 20:50
  5. Display animated images
    By suresh in forum Qt Programming
    Replies: 1
    Last Post: 27th January 2007, 21:53

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
  •  
Qt is a trademark of The Qt Company.