【发布时间】:2011-06-21 05:50:53
【问题描述】:
有时我的应用程序在非 GUI 线程中执行的 QWidget::update() 中崩溃。
我正在开发一个应用程序,它从远程主机接收视频帧并将它们显示在 QWidget 上。
为此,我使用了 libVLC 库,它为我提供了一个解码图像。我在 libVLC 回调中收到图像,该回调在单独的 libVLC 线程中执行。在这个回调中,我试图执行 QWidget::update() 方法。有时应用程序崩溃,并且调用堆栈在此方法中的某个位置。这是我的回调代码:
//! 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 返回主事件循环时安排一个绘制事件进行处理,并且不会导致立即重绘。
问题是:“不允许在主线程之外进行GUI操作”的规则是否适用于QWidget::update()?该操作是否属于“GUI操作”?
我使用 Qt 4.7.3,崩溃在 Windows 7 和 Linux 上重现。
【问题讨论】:
-
您确定您的
void* picture确实是QImage*? -
你用的是什么qt版本?
-
是的,我在 lockCB() 方法中将此指针传递给 libVLC。
-
应用程序通常工作正常,但有时会崩溃,并且此类小部件打开的次数越多,崩溃的频率越高。
-
我认为删除在其他方法中保留的对象不是一个好习惯。是否在代码的其他站点中使用“void* 图片”实例?尽量不要删除收到的“void*图片”,在创建的方法中删除这个对象。问候。
标签: qt thread-safety libvlc