【问题标题】:frequently update QLabel with image data from server经常使用来自服务器的图像数据更新 QLabel
【发布时间】:2012-01-01 20:15:36
【问题描述】:

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

【问题讨论】:

    标签: qt sockets qwidget qthread synchronisation


    【解决方案1】:

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

    另一种方法是在您的对象中创建布尔变量processing,如果您正在处理数据,则将其设置为true。在将其设置回 false 之前,您调用 QCoreApplication::processEvents(); 来处理事件队列中的所有事件。在您的插槽中,您应该检查是否设置了 processing 变量,如果设置了则跳过任何操作。这是一个简单粗暴的灵魂,但它确实有效。请注意,如果您的 GUI 线程中有其他事件处理程序调用 processEvents();(例如,不止一个这样的标签),一些标签可能会完全停止获取它们的数据(冻结)。

    您可能很想使用Qt::BlockingQueuedConnection 来阻止网络线程在处理完成之前接收任何内容,但由于许多不同的原因,这是一个坏主意(如果您像那样同步它,那么为什么需要单独的线程呢? )

    【讨论】:

    • 我把socket放在线程中,因为用户应该能够使用GUI。在我的例子中,如果用户按下某个按钮,一些命令将被发送到服务器。对于发送命令,我使用其他套接字连接。这就是为什么我将图像接收器套接字放在线程中,它不应该阻塞用户与程序的交互。
    • 我的意思是'如果你会像那样同步它,那你为什么需要单独的线程呢?无论如何,第一个解决方案应该是个好主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多