Search code examples
qtthread-safetylibvlc

Using QWidget::update() from non-GUI thread


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 host and display them on QWidget.

For this purpose I use libVLC library that gives to me a decoded image. I receive image in libVLC callback, that is performing in separate libVLC thread. In this callback I'm trying to perform QWidget::update() method. Sometimes application crashes, and callstack is somewhere in this method. Here is the my callback code:

//! Called when a video frame is ready to be displayed, according to the vlc clock. 
//! \c picture is the return value from lockCB().

void VideoWidget::displayCB(void* picture)
{
    QImage* image = reinterpret_cast<QImage*>(picture);

    onScreenPixmapMutex_.lock();
    onScreenPixmap_ = QImage(*image);
    onScreenPixmap_.detach();
    onScreenPixmapMutex_.unlock();

    delete image;

    update();
}

I know that GUI operations outside the main thread are not allowed in Qt. But according documentation QWidget::update() just schedules a paint event for processing when Qt returns to the main event loop and does not cause an immediate repaint.

The questtion is: is the rule "GUI operations outside the main thread are not allowed" appliable for QWidget::update()? Does this operation belong to "GUI operations"?

I use Qt 4.7.3, the crash repoduces on Windows 7 and Linux.


Solution

  • The question is: is the rule "GUI operations outside the main thread are not allowed" applicable for QWidget::update()? Does this operation belongs to "GUI operations"?

    Yes. Update belongs to GUI operations. According to the documentation, all QWidget and derived classes can only be used by the main thread. This is general, and specific functions may state that they are thread safe, but in this case update() does not, so it is not safe to call from other threads.

    The signal/slot mechanism works because Qt will (unless told otherwise) use events to allow slots in one thread to be triggered by signals in another. If you were to use signals/slots and tell Qt not to do the special thread handling, the crashes would reappear.