2

我正在尝试创建一个库,其 API 将以下列方式使用:

WebService *service = new WebService( username, password );
User *user = service->getAuthenticatedUser();
UserAssets *assets = user->assets();
// And so on

创建实例时,经过身份验证的用户及其资产都不会被下载WebServer,而是只有在明确请求时才会被检索。

每当我必须在使用 Qt 之前从网络中检索数据时,我都会遵循将finished()信号连接QNetworkReply到适当插槽并使用该插槽处理返回数据的标准模式。

我的问题是该模式似乎不适合我想要的用例。我希望我的图书馆的用户(其他开发人员)能够使用单行来请求和接收他们想要的数据,但至少从我的角度来看,“Qt 方式”似乎要求他们启动一条线上的请求,然后将一些信号连接到其他插槽以获取数据,这不是我希望他们拥有的体验。

我是网络编程的新手,无论是一般的还是 Qt 的,但我使用了用 Python 编写的库,与完全相同的服务进行通信,能够实现这一点,所以这似乎是可能的。

是否可以通过一个函数调用使用 Qt 执行 HTTP 请求的整个生命周期?

4

2 回答 2

1

您最好的选择可能是使用QEventLoop。这将允许您 1) 启动 HTTP 连接,并且从调用者的角度来看,2) 有效阻止,直到您得到响应。

例如:

于 2012-09-01T23:45:35.637 回答
0

正如其他人已经提到的,您可以使用QEventLoop等待finished()error()信号,以及退出事件循环。这种解决方案在工作时有一些严重的缺点。

如果下载给定地址需要更长的时间,那么您可能会在事件循环中卡住很长一段时间。事件循环很好地处理事件,因此您的应用程序不会冻结,但无论如何都有一些怪癖。想象一下,用户正在等待加载,然后按下另一个按钮来加载其他内容。然后你将有多个循环,第一个文件必须等待第二个文件完成下载。

在单个调用中做事向许多程序员暗示,这将在一瞬间发生。但是您的函数正在内部处理事件,因此这可能不成立。想象一个像这样的代码

// some pointer accessible to many functions/methods (eg. member, global)
MyData* myData=0;

然后是调用您的函数的代码:

if (myData){
    QNetworkReply* reply = getMyWobsite(whatever);
    myData->modify(reply);
}

看起来不错,但是如果其他插槽碰巧调用了怎么办

    myData=0;

如果在等待请求时执行此槽,应用程序将崩溃。如果您决定在您的函数中使用 QEventLoop,请务必在函数文档中提及它,这样使用它的程序员将能够避免此类问题。

如果您没有将 qt 用于其他任何事情,您甚至可以考虑一些替代库(例如libcurl),它们可能已经实现了您需要的东西。

于 2012-09-02T03:20:43.840 回答