从非 GUI 线程使用 QWidget::update() [英] Using QWidget::update() from non-GUI thread

查看:35
本文介绍了从非 GUI 线程使用 QWidget::update()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时我的应用程序会在非 GUI 线程中执行的 QWidget::update() 中崩溃.

Sometimes my application crashes in QWidget::update() that is performing in non-GUI thread.

我正在开发一个应用程序,它从远程主机接收视频帧并将它们显示在 QWidget 上.

I am developing an application in which receives video frames from remote host and display them on QWidget.

为此,我使用了 libVLC 库,它为我提供了一个解码图像.我在 libVLC 回调中收到图像,这是在单独的 libVLC 线程中执行的.在这个回调中,我试图执行 QWidget::update() 方法.有时应用程序会崩溃,并且调用堆栈位于此方法中的某处.这是我的回调代码:

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();
}

我知道 Qt 中不允许在主线程之外进行 GUI 操作.但是根据文档 QWidget::update() 只是在 Qt 返回主事件循环时安排了一个绘制事件进行处理,并且不会立即导致重新绘制.

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.

问题是:QWidget::update()是否适用不允许主线程外的GUI操作"的规则?这个操作属于GUI操作"吗?

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"?

我使用 Qt 4.7.3,崩溃在 Windows 7 和 Linux 上重现.

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

推荐答案

问题是:规则GUI主线程之外的操作是不允许"适用于QWidget::更新()?有没有这个操作属于GUI操作"吗?

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"?

是的.更新属于GUI操作.根据文档,所有QWidget和派生类只能被主线程使用.这是通用的,特定的函数可能会声明它们是线程安全的,但在这种情况下 update() 不是,因此从其他线程调用是不安全的.

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.

信号/槽机制之所以起作用,是因为 Qt 将(除非另有说明)使用事件来允许一个线程中的槽被另一个线程中的信号触发.如果您要使用信号/槽并告诉 Qt 不要进行特殊的线程处理,崩溃会再次出现.

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.

这篇关于从非 GUI 线程使用 QWidget::update()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆