2012-01-01 42 views
0

我正在寫一個程序,它應該在QWidget中顯示QLabel中的圖像。圖像從服務器發送。首先,我有一個負責連接和從服務器接收數據的線程。當收到數據時,套接字線程將發送一個信號gotNewData(Imagedata),該信號連接到QWidgetupdateImage(Imagedata)插槽。在updateImage(Imagedata)插槽中,我將從服務器獲取的圖像數據轉換爲QImage,縮放圖像並創建QPixmap,我將其設置爲QLabel。我的問題是,在處理updateImage(Imagedata)函數的過程中,套接字會獲得其他包含新映像的包,並將信號一次又一次地發送到QWidget。這是合乎邏輯的,因爲套接字線程不關心前一次信號調用調用的函數updateImage(Imagedata)是否已經完成。我的問題是:是否有一些技巧,我如何能夠與QWidgetupdateImage(Imagedata)函數同步我的套接字線程?經常更新QLabel與來自服務器的圖像數據

回答

0

確實有。問題是,如果在處理舊圖像時接收到新圖像,您希望達到什麼目的。如果你想跳過新的並且處理舊到最後,我會建議在發送對象時調用blockSignals - 這會破壞調用者和calle指針,但qt似乎不允許阻止接收信號,只是發送。 修改不會影響性能太多,也不會混淆可能會完成的其他通信網絡,可能會在包含標籤的窗口小部件中創建代理QObject,然後使用moveToThread()將其移至網絡線程並在其上使用blockSignals這個對象。自然地,這個對象需要與發送的實際信號相同的簽名信號。創建的對象雖然具有不同的線程關聯性,但在邏輯上仍然由GUI小部件擁有,並且應該由它刪除。

另一種方法是在您的對象中創建bool變量processing,如果您正在處理數據,則將其設置爲true。在將其設置回false之前,您可以撥打QCoreApplication::processEvents();來處理事件隊列中的所有事件。在你的插槽中,你應該檢查是否設置了processing vaiable,如果是,跳過任何事情。這是一種簡單而粗俗的靈魂,但它起作用。請注意,如果您的其他事件處理程序在您的GUI線程中調用processEvents();(例如,多個此類標籤),則某些標籤可能會停止獲取其數據(凍結)。

在處理完成之前,您可能會試圖使用Qt::BlockingQueuedConnection來阻止網絡線程接收任何東西,但是由於許多不同的原因,這是一個壞主意(如果您像這樣同步它,那麼爲什麼您需要單獨的線程呢?)

+0

我把套接字放在線程中,因爲用戶應該可以使用GUI。就我而言,如果用戶按下某個按鈕,一些命令將被髮送到服務器。爲了發送命令,我使用其他套接字連接。這就是爲什麼我把圖像接收器套接字放在線程中,它不應該阻止用戶與程序的交互。 – 2012-01-02 00:07:16

+0

我的意思是'如果你會像這樣同步它,那麼爲什麼你需要單獨的線程?'無論如何,第一個解決方案應該是一個好主意。 – 2012-01-02 01:24:03

相關問題