Results 1 to 9 of 9

Thread: update a wigdet in a thread is no allow?

  1. #1
    Join Date
    Aug 2009
    Posts
    28
    Thanks
    5
    Thanked 1 Time in 1 Post

    Unhappy update a wigdet in a thread is no allow?

    hi,guys:
    i receive some picture data from internet,and now want to display in a widget with my form.(ON RED HAT ENTERPRISE Linux 5.0)
    the "widget" is inherited from QWidget, and use these code to attatch to the mainform:

    ui->widget->setVisible(0); //a Widget to provide geometry
    //define as : class WidgetVideoArea : public QWidget

    videoarea = new WidgetVideoArea(this);
    videoarea->setGeometry(ui->widget->geometry());
    videoarea->show();

    then ,i recevie data from thread1,and emit a signal to mainwindow,so the picture can update.

    Qt Code:
    1. void MainWindow::updateVideo(QByteArray videobufs)
    2. {
    3. const char *data = videobufs.constData();
    4. QImage smage((uchar*)data,240,320,QImage::Format_RGB16);
    5. videoarea->setRepaintFlag(smage);
    6. videoarea->repaint();
    7. }
    To copy to clipboard, switch view to plain text mode 
    now it works.
    But i think that will freeze GUI. so i create another thread,thread2, to update the picture separately.
    the function updateVideo(QByteArray videobufs) above is set to "public",so i can use it in thread2.
    However,when i do that, application output:

    X Error: BadDrawable (invalid Pixmap or Window parameter) 9
    Major opcode: 62 (X_CopyArea)
    Resource id: 0x0
    QPixmap: It is not safe to use pixmaps outside the GUI thread
    ...............
    so how can i update the widget in a thread? will these appear in embedded board?(i will port to ARM later).
    i used this method in VisualC++ before, and had no problem.
    thanks.

  2. #2
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: update a wigdet in a thread is no allow?

    correct: you may only use QWidgets from the main aka gui thread.

    you may produce a QImage in another thread, though. pass it to the main thread (eg using signal/slot, which is thread safe) and paint it there.

    HTH

  3. #3
    Join Date
    Aug 2009
    Posts
    28
    Thanks
    5
    Thanked 1 Time in 1 Post

    Smile Re: update a wigdet in a thread is no allow?

    hi:
    Quote Originally Posted by caduel View Post
    you may produce a QImage in another thread, though. pass it to the main thread (eg using signal/slot, which is thread safe) and paint it there.
    ==>>that's what i have done
    SO, can i only pass a QImage to main thread through another thread?
    if the picture is recevied quickly(eg, 30fps), in the gui main thread, will the window be slower or look like freeze?
    BTW,is there a double buffer(like VisualC++ MFC) concept in QT?

  4. #4
    Join Date
    Aug 2009
    Posts
    28
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: update a wigdet in a thread is no allow?

    hello?..............

  5. #5
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: update a wigdet in a thread is no allow?

    Double buffering is enabled by default in Qt.

    btw
    For rapidly updating custom widgets that constantly paint over their entire areas with opaque content, such as video streaming widgets, it is better to set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead associated with repainting the widget's background.
    I you call QWidget::update() instead of QWidget::repaint(), your window will stay responsive, but some frames might not be drawn.

  6. #6
    Join Date
    Aug 2009
    Posts
    28
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: update a wigdet in a thread is no allow?

    thanks.
    could you show me how to use the update() member function(to paint a QImage to my custom widget area)?
    it seems like no examples available....
    now i use this method:

    Qt Code:
    1. void WidgetVideoArea::paintEvent(QPaintEvent*pPaintEvent)
    2. {
    3. if(repaintme)
    4. {
    5. target.setX(0);
    6. target.setY(0);
    7. target.setWidth(width());
    8. target.setHeight(height());
    9.  
    10. painter.begin(this);
    11. painter.drawImage(target,image);
    12. painter.end();
    13.  
    14. repaintme = false;
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by lanmanck; 24th October 2009 at 06:29. Reason: have to

  7. #7
    Join Date
    Dec 2006
    Posts
    849
    Thanks
    6
    Thanked 163 Times in 151 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: update a wigdet in a thread is no allow?

    update() schedules a repaint-Event. Qt will repaint your widget when it has the time and when it is necessay.

    If your image is large, you might want to consider QPaintEvent::rect().
    This repaintme stuff should not be necessary. What do you use it for?
    (A repaint could be scheduled, because another window obscured your widget. Yes, with buffering maybe not, but it could.)

  8. The following user says thank you to caduel for this useful post:

    lanmanck (25th October 2009)

  9. #8
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: update a wigdet in a thread is no allow?

    Qt Code:
    1. void WidgetVideoArea::newImage(const QImage& image)//slot
    2. {
    3. this->image = image;
    4. update();
    5. }
    6.  
    7. void WidgetVideoArea::paintEvent(QPaintEvent*pPaintEvent)
    8. {
    9. QPainter painter(this);
    10. painter.drawImage(image, ...);
    11. }
    To copy to clipboard, switch view to plain text mode 

  10. The following user says thank you to spud for this useful post:

    lanmanck (25th October 2009)

  11. #9
    Join Date
    Aug 2009
    Posts
    28
    Thanks
    5
    Thanked 1 Time in 1 Post

    Default Re: update a wigdet in a thread is no allow?

    yes ,i use update() to replace repaint() ,and found it worked.
    BTW,the "repaintme" stuff is used in my old project ,and i removed it now.
    thanks everyone .

Similar Threads

  1. update widget from separate thread
    By method in forum Qt Programming
    Replies: 5
    Last Post: 10th July 2009, 14:33
  2. Thread Ownership Problem
    By tntcoda in forum Qt Programming
    Replies: 1
    Last Post: 9th June 2009, 00:18
  3. Thread Help
    By tntcoda in forum Qt Programming
    Replies: 1
    Last Post: 16th January 2009, 22:10
  4. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  5. Problem closing a QMainWindow in Qt4.2
    By ian in forum Qt Programming
    Replies: 11
    Last Post: 17th October 2006, 00:49

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.