我正在编写一个程序,它应该QLabel
在QWidget
. 图像是从服务器发送的。首先,我有一个线程负责连接并从服务器接收数据。当接收到数据时,套接字线程发送一个信号gotNewData(Imagedata)
,该信号连接到QWidget
updateImage(Imagedata)
插槽。在updateImage(Imagedata)
插槽中,我将从服务器获取的图像数据转换为QImage
、缩放图像并创建QPixmap
,并将其设置为QLabel
. 我的问题是,在处理功能期间,套接字获取带有新图像的其他包并一次又一次updateImage(Imagedata)
地发送信号。QWidget
这是合乎逻辑的,因为套接字线程不关心函数是否updateImage(Imagedata)
,由前一个信号调用调用,是否已经完成。我的问题是:是否有一些技术,我如何将我的套接字线程与QWidget
updateImage(Imagedata)
函数同步?
1 回答
肯定有的。问题是,如果在处理旧图像的同时收到新图像,您究竟想要实现什么。如果你想跳过新的并处理旧的直到最后,我建议在发送对象上调用 blockSignals - 这会破坏调用者和被调用者的spearation,但 qt 似乎不允许阻止接收信号,只是发送。可能会完成不会对性能影响太大并且不会混淆其他通信网络线程的修改,将是在包含标签的小部件中创建代理 QObject,然后使用 moveToThread() 将其移动到网络线程,并在此使用 blockSignals目的。自然地,该对象需要与发送的实际信号具有相同签名的信号。创建的对象虽然具有不同的线程亲和性,但逻辑上仍归 GUI 小部件所有,
另一种方法是在您的对象中创建 bool 变量processing
,如果您正在处理数据,则将其设置为 true。就在将其设置回 false 之前,您调用QCoreApplication::processEvents();
which 处理事件队列中的所有事件。在您的插槽中,您应该检查是否processing
设置了 vaiable,如果设置了则跳过任何操作。这是一个简单粗暴的灵魂,但它确实有效。请注意,如果您processEvents();
的 GUI 线程中有其他事件处理程序调用(例如,多个这样的标签),一些标签可能会停止获取它们的数据(冻结)。
您可能很想Qt::BlockingQueuedConnection
在处理完成之前阻止网络线程接收任何内容,但由于许多不同的原因,这是一个坏主意(如果您像那样同步它,那么您为什么需要单独的线程呢?)