【发布时间】:2016-03-25 22:14:17
【问题描述】:
我想在 Qt 中实现某种回调。
我有一个名为 ApiHandler 的类来发出请求。我应该有办法将一个函数作为回调传递给 makeRequest 并在 replyFinished 时执行它。 我知道一种使用 std::function/std::bind 的方法。但也许有办法使用 Qt 做到这一点?插槽?或者关于在这种情况下使用 std::function/std::bind 的更详细说明。
谢谢!
typedef void (*callback)();
void ApiHandler::makeRequest(QString method, QMap<QString, QString> parameters, callback)
{
QUrl url = this->buildCall(method, parameters);
connect(this->manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*, callback)));
QNetworkRequest request;
request.setUrl(url);
request.setRawHeader("User-Agent", "Test");
QNetworkReply *reply = this->manager->get(request);
connect(reply, SIGNAL(readyRead()), this, SLOT(slotReadyRead()));
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError)));
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(slotSslErrors(QList<QSslError>)));
}
void ApiHandler::replyFinished(QNetworkReply* reply, callback)
{
qDebug() << "replyFinished" << reply->url();
QJsonDocument j = QJsonDocument::fromJson(reply->readAll());
if (j.isEmpty()) {
// throw error
}
// call the callback with "j" as parameter
// callback(j)
reply->deleteLater();
}
【问题讨论】:
-
什么情况下使用?只有在编译时无法解析回调时,您才需要 std::function。如果你事先知道所有的回调,那么就让它们成为插槽。
-
我可以拨打不同的电话,例如
QMap<QString, QString> m; m["user_id"] = this->settings.value(USER_ID).toString(); ApiHandler *a = new ApiHandler; a->makeRequest("users.isAppUser", m, testCallback);我应该需要传递不同的回调。例如,如果我从应用程序开始调用它,我会传递回调以显示警告,如果我从关于窗口调用它,我会传递回调以显示任何用户正在使用应用程序。 -
您要么使用不同的对象,用于不同的信号,要么使用disconnect and connect slots 上下文
-
你基本上需要一个代理来将
reply转换为j,那为什么不做一个这样的代理类呢?就像当你makeRequest你new和代理时,然后将代理的接收端连接到回复并将发送端连接到回调。