2016-07-04 45 views
0

我有Qt應用程序,有一些外部庫依賴關係。我的應用程序和外部庫不使用線程(在我看來)。他們的來源中沒有thread單詞。一個庫有衍生自QTcpServerlisten()方法重載。 (OS是windows)Qt內部線程

我在Window類的構造函數中創建一個對象並調用listen()方法。

的QObject:在listen()方法調用出現在控制檯的警告信息不能爲父母是在不同的線程 創建的兒童。 (Parent是QJsonRpcTcpServer(0x4c1b38),父母的線程是 的QThread(0x4a8d98),當前線程的QThread(0x47e348)

Qt的子系統等創建額外的線程,他們中的一個UI線程等一些網或存在交集或別的東西。該程序不正常。工作後(TCP客戶端connect和謊言,直到程序沒有關閉)

什麼是可能的載體來調試問題?

Window::Window(QWidget *parent) { 
    Service* service = new Service(parent); 
    QJsonRpcTcpServer* rpcServer = new QJsonRpcTcpServer(parent); 
    rpcServer->addService(service); 
    // problem at next line: 
    if (rpcServer->listen(QHostAddress::Any, 42123)) { 
    } 
} 

一些新的信息,當我替換QJsonRpc時TcpServer與QTcpServer然後在listen()警告呼叫消失。

一些更多的新信息,問題是在Windows上。在FreeBSD上構建和運行是可以的 - 沒有錯誤並按預期工作。

+0

在調試器中運行您的應用程序,並在新線程的產生中添加斷點;確切的方法取決於您使用的調試器。 –

+1

只是不要將父母設置爲Sevice和QJsonRpcTcpServer。使用'connect(parent,&QObject :: destroyed,obj,&QObject :: deleteLater);'調用釋放內存 –

+0

@DmitrySazonov,該信號很有用,但對於所有不以QObject派生的純C++對象開始的情況, – AlexanderVX

回答

2

如何處理調試消息和工作線程阻止啓動的事實?我得到: 「無法爲處於不同線程的父級創建子項。」消息在調試輸出中。

有幾種方法來動態地分配對象,並且仍然保持在Qt中它的軌道,而無需使用QObject鹼與父(所有者)傳遞給它。例如QScopedPointer作爲一類「父」對象,而不是成員:

/// snip /// 
#include <QScopedPointer> 
class Service; 
class QJsonRpcTcpServer; 

class Window : public QWidget 
{ 
    /// snip /// 
    QScopedPointer<Service> m_service; 
    QScopedPointer<QJsonRpcTcpServer> m_rpcServer; 
}; 

/// snip /// 

Window::Window(QWidget *parent) { 
    m_service.reset(new Service(nullptr));    // unsure of default 
    m_rpcServer.reset(new QJsonRpcTcpServer(nullptr)); // constructor, take nullptr 
    m_rpcServer->addService(m_service); 
    // was problem at next line: not anymore 
    if (m_rpcServer->listen(QHostAddress::Any, 42123)) { 
    } 
} 

我還懷疑QJsonRpcTcpServer::addService正在釋放「服務」對象的責任。但是我不能用文檔證明,所以也儘量找到答案。請注意,QScopedPointerstd::unique_ptr將始終工作確定性,但QObject::destroyed信號通過QObject::deletelater執行延期發佈更容易從發佈對象時發生「驚喜」開始。