Sometimes my application crashes in QWidget::update() that is performing in non-GUI thread.
I am developing an application in which receives video frames from remote
All you need to do to update a pixmap from any thread is to execute the relevant code in the main thread. This takes care of all the locking and everything else. Modern multithreaded programming is supposed to be easy: if it isn't, you might be trying too hard :)
For example, supposing that you're using a QLabel
to display the image (why reinvent your own widget?!):
/// This function is thread-safe. It can be invoked from any thread.
void setImageOn(const QImage & image, QLabel * label) {
auto set = [image, label]{
label->setPixmap(QPixmap::fromImage(image));
};
if (label->thread() == QThread::currentThread())
set();
else {
QObject sig;
sig.connect(&sig, &QObject::destroyed, label, set);
}
}
Now, you might as well do things right and drop stale images - there's no point to setting an image if there are newer images in the event queue ahead of it. That would be the only reason to use a custom widget. See this answer for details.
Side note (does't apply to your code): If you have to call QWidget::update
from outside of the widget's implementation, you're doing something very wrong. If you're using a stock Qt widget, you should never need to do it. If you have your own widget and it needs its user to call update
on it, you've designed it wrong. That's all there's to it.