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.
Code:
void MainWindow
::updateVideo(QByteArray videobufs
) {
const char *data = videobufs.constData();
videoarea->setRepaintFlag(smage);
videoarea->repaint();
}
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.
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
Re: update a wigdet in a thread is no allow?
hi:
Quote:
Originally Posted by
caduel
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?
Re: update a wigdet in a thread is no allow?
Re: update a wigdet in a thread is no allow?
Double buffering is enabled by default in Qt.
btw
Quote:
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.
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:
Code:
void WidgetVideoArea
::paintEvent(QPaintEvent*pPaintEvent
) {
if(repaintme)
{
target.setX(0);
target.setY(0);
target.setWidth(width());
target.setHeight(height());
painter.begin(this);
painter.drawImage(target,image);
painter.end();
repaintme = false;
}
}
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.)
Re: update a wigdet in a thread is no allow?
Code:
void WidgetVideoArea::newImage(const QImage& image)//slot
{
this->image = image;
update();
}
void WidgetVideoArea
::paintEvent(QPaintEvent*pPaintEvent
) {
painter.drawImage(image, ...);
}
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 .