2015-11-05 64 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