Singleton QNetworkAccessManager 没有将响应定向到所需的形式
Singleton QNetworkAccessManager not directing the response to desired form
在一个小型 Qt 应用程序中,我有一个封装在单例中的 NetworkAccessManager(NAM) class。此 class 的 NAM 对象由四个独立的形式 classes 使用。每个表单 class 都会向单独的 php 发出请求(并且 php 至少需要 3 秒的睡眠(3))。
现在有两种情况:
情况一:当 NAM 为每个表单连接到表单在构造函数中的插槽时。
在这种情况下,当我同时发送所有四种形式的请求时;所有响应都指向一个表单(第一个触发请求的表单),而不是请求它的表单。
情况 II:当 NAM 连接(用于触发请求)和断开连接(当收到响应时)到窗体的 slot IN FUNCTIONS(而不是构造函数)。
在这种情况下,当我同时从所有四种形式发送请求时(即不到 3 秒);然后只返回第一个响应,其余的永远不会返回。这与代码一致,因为单例 NAM 在收到第一个请求的回复后立即断开连接。因此无法处理其他请求。
所有形式 class 都是相同的并且使用相同的代码。这是代码(特定于案例 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 对象时,代码可以正常工作 class。
但是我如何实现预期的行为(整个应用程序使用一个 NAM),即响应仅针对请求它的表单,并且对其他表单的请求不应该受到影响?
我的建议(我所做的)是跟踪哪个对象向管理器发出请求,也许更新您的管理器以接收对象指针
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));
(未测试,但您应该明白)
[编辑:固定代码]
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
的信号。请注意,finished()
信号中没有 QNetworkReply *reply
参数:
void Request2::slotReplyFinished(){
ui->TEdit_Req2->setText(m_Reply->readAll());
m_Reply->deleteLater();
}
在一个小型 Qt 应用程序中,我有一个封装在单例中的 NetworkAccessManager(NAM) class。此 class 的 NAM 对象由四个独立的形式 classes 使用。每个表单 class 都会向单独的 php 发出请求(并且 php 至少需要 3 秒的睡眠(3))。
现在有两种情况:
情况一:当 NAM 为每个表单连接到表单在构造函数中的插槽时。 在这种情况下,当我同时发送所有四种形式的请求时;所有响应都指向一个表单(第一个触发请求的表单),而不是请求它的表单。
情况 II:当 NAM 连接(用于触发请求)和断开连接(当收到响应时)到窗体的 slot IN FUNCTIONS(而不是构造函数)。 在这种情况下,当我同时从所有四种形式发送请求时(即不到 3 秒);然后只返回第一个响应,其余的永远不会返回。这与代码一致,因为单例 NAM 在收到第一个请求的回复后立即断开连接。因此无法处理其他请求。
所有形式 class 都是相同的并且使用相同的代码。这是代码(特定于案例 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 对象时,代码可以正常工作 class。
但是我如何实现预期的行为(整个应用程序使用一个 NAM),即响应仅针对请求它的表单,并且对其他表单的请求不应该受到影响?
我的建议(我所做的)是跟踪哪个对象向管理器发出请求,也许更新您的管理器以接收对象指针
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));
(未测试,但您应该明白)
[编辑:固定代码]
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
的信号。请注意,finished()
信号中没有 QNetworkReply *reply
参数:
void Request2::slotReplyFinished(){
ui->TEdit_Req2->setText(m_Reply->readAll());
m_Reply->deleteLater();
}