经常用来自服务器的图像数据更新QLabel

时间:2012-01-01 20:15:37

标签: qt sockets qwidget qthread synchronisation

我正在编写一个程序,该程序应该在QLabel的{​​{1}}中显示图像。图像从服务器发送。首先,我有一个线程负责连接和从服务器接收数据。收到数据后,套接字线程发送一个信号QWidget,该信号连接到gotNewData(Imagedata) QWidget插槽。在updateImage(Imagedata)广告位中,我将图片数据(我从服务器获取的图片数据转换为updateImage(Imagedata),缩放图片并创建QImage,我将其设置为QPixmap。我的问题是,在处理QLabel函数期间,套接字获取带有新图像的其他包,并一次又一次地将信号发送到updateImage(Imagedata)。这是合乎逻辑的,因为套接字线程不关心由前一个信号调用调用的函数QWidget是否已经完成。我的问题是:是否有一些技巧,如何将我的套接字线程与updateImage(Imagedata) QWidget函数同步?

1 个答案:

答案 0 :(得分:0)

肯定有。问题是,如果在处理旧图像时收到新图像,您希望实现什么?如果你想跳过新的并且处理旧的直到最后,我会建议在发送对象时调用blockSignals - 这会破坏调用者和calle spearation,但是qt似乎不允许阻止接收信号,只是发送。 修改不会影响性能,并且不会混淆其他可能完成的通信网络,将在包含标签的小部件中创建代理QObject,然后使用moveToThread()将其移动到网络线程,并在此使用blockSignals宾语。当然,该对象需要与发送的实际信号具有相同签名的信号。创建的对象虽然具有不同的线程亲和力,但在逻辑上仍将由GUI小部件保留,并应由其删除。

另一种方法是在对象中创建bool变量processing,如果要处理数据,则将其设置为true。在将其设置为false之前,您调用QCoreApplication::processEvents();来处理事件队列中的所有事件。在你的插槽中,你应该检查是否设置了processing vaiable,如果是,则跳过做任何事情。这是一个简单粗暴的灵魂,但它有效。请注意,如果您的GUI线程中有其他事件处理程序调用{​​{1}}(例如,多个标签),则某些标签可能会停止获取其数据(冻结)。

您可能很想使用processEvents();来阻止网络线程在处理完成之前收到任何内容,但这有很多不同的原因(如果您将其同步,那么为什么需要单独的线程)所有?)