2015-11-05 11 views
1

響應在小型Qt應用程序,我有包裹在一個單獨的類一個NetworkAccessManager(NAM)。這個類的NAM對象被四個獨立的表單類使用。每個表單類都會向一個單獨的php發出請求(並且PHP在睡眠(3)期間至少需要3秒鐘)。辛格爾頓QNetworkAccessManager不引導至所需的形式

現在有兩種情況:

案例一:當NAM,每種形式,連接形式的插槽構造函數。 在這種情況下,當我同時從所有四種形式發送請求;所有響應被定向到的一種形式(就是那個最早是在射擊的要求),而不是請求它的形式。

情況II:當NAM連接(燒成請求)和斷開(當接收到的應答),以形成的函數槽(而不是構造函數)。 在這種情況下,當I(即,在小於3秒)發送請求同時從所有四種形式;那麼只有第一個響應返回,其餘的不會返回。這與代碼一致,因爲一旦收到第一個請求的回覆,單身NAM即被斷開連接。因此其他請求無法處理。

所有形式的類是相同的,使用相同的代碼。下面是代碼(案例二專用):

void Request2::slotStartRequest(){ 
    m_Req2 = NetworkAccessManager::getInstance(); 
    connect(m_Req2, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotReplyFinished(QNetworkReply*))); 
    QString postData = "value=222"; 
    m_Req2->post(QNetworkRequest(QUrl(path)), postData.toUtf8()); 
} 

void Request2::slotReplyFinished(QNetworkReply *reply){ 
    disconnect(m_Req2, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotReplyFinished(QNetworkReply*))); 
    ui->TEdit_Req2->setText(reply->readAll()); 
    reply->deleteLater(); 
} 

雖然這兩種情況的代碼非常相似。此代碼是特定於案例II的。對於案例I,唯一的變化是'connect'和'getInstance'代碼放在構造函數中(並且沒有'斷開連接')。

該代碼可以正常使用每個表單類的一個NetworkAccessManager對象。

但是,如何實現所需的行爲(對於整個應用程序,只有一個NAM):響應僅針對請求它的表單,並且其他表單的請求不應受到影響?

回答

2

不結盟國家運動功能post()創建一個新的QNetworkReply實例來管理該請求。它可以直接連接到QNetworkReply信號,而不是QNetworkAccessManager信號:

void Request2::slotStartRequest(){ 
    QString postData = "value=222"; 
    QNetworkAccessManager *nam = NetworkAccessManager::getInstance(); 
    m_Reply = nam->post(QNetworkRequest(QUrl(path)), postData.toUtf8());  
    connect(m_Reply, SIGNAL(finished()), this, SLOT(slotReplyFinished())); 
} 

現在的QNetworkReply *m_Reply只有這個實例可以調用this信號。需要注意的是,沒有QNetworkReply *reply說法在finished()信號:

void Request2::slotReplyFinished(){ 
    ui->TEdit_Req2->setText(m_Reply->readAll()); 
    m_Reply->deleteLater(); 
} 
+0

那麼,你再次幫助我。很高興與您的支持:-) – Jatin

+0

那麼,如果我必須從一個單一的形式與Singleton NAM兩個同時請求;那麼我需要兩個QNetworkReply對象嗎?或者還有其他更簡單的方法嗎? – Jatin

+0

@Jatin對於兩個請求,你將有兩個'QNetworkReply'對象。這取決於您的項目設計如何處理這些答覆。你可以有兩個不同的'Request2'實例,每個這樣的實例可以使用它自己的回覆。可以使用一個「請求2」和多個回覆。 –

0

我的建議(我做什麼)是跟蹤哪些對象進行對經理的要求,也許更新您的經理採取了對象指針

m_Req2->post(QNetworkRequest(QUrl(path)), postData.toUtf8(), this); 

然後在管理,使用指針並使用QMetaObject調用該方法,而不是發出信號:http://doc.qt.io/qt-5/qmetaobject.html#invokeMethod

所以,你得到這樣的事情,對經理

QMetaObject::invokeMethod(obj, "slotReplyFinished", Qt::DirectConnection, 
         Q_ARG(QNetworkReply*, reply)); 

(未測試,但你應該明白我的意思)

[編輯:固定碼]

+0

對於這種情況也許Qt的:: Directconnection是不是你所需要的,也許排隊,但如果您需要直接連接,也許考慮的接口,並直接調用方法在傳遞的對象'obj-> slotReplyFinished(回覆)' –

+0

我對你的跟蹤對象的建議很好。在Manager中,我使用了[qRegisterMetaType (「QNetworkReply *」);因爲slotReplyFinished需要QNetworkReply *(而不是你所說的QNetworkReply),所以QMetaObject :: invokeMethod(obj,「slotReplyFinished」,Qt :: QueuedConnection,Q_ARG(QNetworkReply *,reply));但是,reply-> readAll()現在是空的。我是否正確使用它?爲什麼回覆內容是空的? – Jatin

+0

還有一點。由於我是使用invokeMethod()的新手,我使用[connect(this,SIGNAL(finished(QNetworkReply *)),obj,SLOT(slotReplyFinished(QNetworkReply *)),Qt :: QueuedConnection);],希望它能夠產生相同的效果(跟蹤對象並調用其槽())。但是它導致了案例I的問題,所有答覆都針對一種形式。這種方法與您的建議不一樣嗎? – Jatin