在一个小型Qt应用程序中,我将NetworkAccessManager(NAM)包装在单例类中。此类的NAM对象由四个独立的表单类使用。每个表单类都会向一个单独的php发出一个请求(而php在睡眠时至少需要3秒钟(3))。
现在有两种情况:
案例I:当每个表单的NAM连接到表单的插槽IN CONSTRUCTOR时。 在这种情况下,当我同时发送来自所有四个表单的请求时;所有回复都只针对一个表单(首先触发请求的表单)而不是表单请求它。
情况II:当NAM连接(用于触发请求)和断开连接(当收到响应时)以形成插槽IN FUNCTIONS(而不是构造函数)。 在这种情况下,当我同时发送来自所有四种表格的请求时(即在不到3秒内);然后只返回第一个响应,其余的都没有返回。这与代码一致,因为单例NAM在收到第一个请求的回复后立即断开连接。因此无法处理其他请求。
所有表单类都相同并使用相同的代码。这是代码(具体案例II):
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'代码放在构造函数中(并且没有'disconnect')。
对于每个表单类,一个NetworkAccessManager对象的代码可以正常工作。
但是,如何实现所需的行为(对于整个应用程序只有一个NAM),响应仅针对请求它的表单,而且其他表单的请求也不应受到影响?
答案 0 :(得分:2)
NAM函数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();
}
答案 1 :(得分:0)
我的建议(我所做的)是跟踪哪个对象在管理器上发出请求,或者更新管理器以接收对象指针
m_Req2->post(QNetworkRequest(QUrl(path)), postData.toUtf8(), this);
然后在Manager上,使用该指针并使用QMetaObject调用该方法,而不是发出信号:http://doc.qt.io/qt-5/qmetaobject.html#invokeMethod。
所以你在经理上得到这样的东西
QMetaObject::invokeMethod(obj, "slotReplyFinished", Qt::DirectConnection,
Q_ARG(QNetworkReply*, reply));
(未经过测试,但您应该明白这一点)
[编辑:固定代码]