2015-08-16 102 views
0

我在專用線程中使用QTcpSocket。關閉此主題,我有一個個人插槽連接disconnected信號的QTcpSocket。該槽包含socket.close()指令。從另一個線程關閉QTcpSocket

class Network 
{ 
    private: 

     QTcpSocket *mp_Socket; 

    public: 

     void connection() 
     { 
     mp_Socket = new QTcpSocket(this); 

     // Move to thread 

     connect(mp_Socket, SIGNAL(disconnected()), this, SLOT(disconnect())); 
     } 

    public slots: 

     void disconnect() 
     { 
     mp_Socket->close(); 
     } 
}; 

在這裏,插槽工作(即使套接字在另一個線程中)。 但是,如果我自己打電話斷開插槽,我有以下錯誤:

「在QSocketNotifier:插座通知者不能從另一個線程關閉」。

爲什麼?

感謝您的幫助。 ;)

+0

您是否嘗試過從另一個線程發出信號? – gengisdave

+0

套接字成員的套接字操作已關閉。 鏈接到外部數據條件。 使追蹤操作變得困難。 – dsgdfg

+0

我試圖發出一個信號作爲與斷開信號的QTcpSocket,但我有同樣的錯誤。 – Maluna34

回答

1

好的,所以你可能需要稍微改變你的設計。不要只將套接字移動到新線程,而應該派生NetworkObject,並將其移動,並使套接字成爲父對象。我以前的答案修正版不起作用,因爲close()沒有在Qt元系統中註冊,因爲它是一個普通的虛擬函數,而不是一個插槽。有了這個新設計,您就可以擁有線程信號和插槽來解決問題。不同線程中的對象之間的連接將自動解析爲排隊並使用事件循環在正確的線程中計劃執行。

此外,我注意到你有一個插槽在你當前的類,沒有它是QObject派生。這是行不通的,你需要Qt的元系統有插槽。您不會收到錯誤,因爲slots在C++中編譯爲無,因此它僅由MOC(元對象編譯器)使用,因此您確實沒有插槽。

當然,這意味着QMetaObject::invokeMethod(yourNetworkClass, "disconnect", Qt::QueuedConnection)現在也可以工作。

+0

「QMetaObject :: invokeMethod:沒有這樣的方法QTcpSocket :: close()」是否正常? – Maluna34

+0

@ Maluna34 - 好像'close()'沒有在元系統中註冊。你使用Qt版本5還是更新? – dtech

+0

我正在使用版本5.4。 – Maluna34