2

I'm attempting to create a library whose API will be used in the following way:

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

Neither the authenticated user, nor their assets, will be downloaded when the WebServer instance is created, rather they will only be retrieved if explicitly requested.

Whenever I've had to retrieve data from the network before using Qt, I've followed the standard pattern of connection the finished() signal of the QNetworkReply to the appropriate slot and using that slot to handle the returned data.

My problem here is that pattern does not seem to accommodate my desired use-case. I would like the users of my library (other developers) to be able to use a single line to request and receive the data they desire, but the 'Qt way' seems, at least from my point of view, to require them to initiate the request on one line, and then connect some signal to some other slot to get the data back, which is not the experience I would like them to have.

I'm new to network programming, both in general and with Qt, but I've used libraries written in Python, communicating with the exact same service, that are able to achieve this, so it does seem to be possible.

Is it possible to perform the full lifecycle of a HTTP request with Qt with a single function call?

2 Answers2

1

Your best bet is probably to use a QEventLoop. This would allow you to 1) initiate the HTTP connection and, from your caller's perspective, 2) effectively block until you get a response.

For example:

Community
  • 1
  • 1
paulsm4
  • 114,292
  • 17
  • 138
  • 190
0

As already other have mentioned you could use QEventLoop to wait for finished() or error() signals, and the quitting event loop. This solution while working, have some serious disadvantages.

If it takes longer to download given address, then you might be stuck in your event loop for quite a while. The event loop is processing events nicely, so your app doesn't frezze, but there are some quirks connected to it anyway. Imagine that user is waiting for load, and then presses another button, to load something else. Then you will have multiple loop-in-loop, and first file will have to wait for the second to finish downloading.

Doing things in single call suggest to many programmers, that this will happen at one instant. But your function is processing events internally, so this might not hold. Imagine a code like

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

Then a code calling your function:

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

Seems fine, but what if some other slot happens to call

    myData=0;

If this slot will be executed while waiting for request, application will crash. If you decide to use QEventLoop in your function, be sure to mention it in function documentation, so programmers using it will be able to avoid such problems.

If you are not using qt for anything else, you might even consider some alternative libraries (eg. libcurl) that might have what you need already implemented.

j_kubik
  • 6,062
  • 1
  • 23
  • 42