In the previous chapters we learned how to use Qnetworkaccessmanager to access the network. On this basis, we have implemented a simple view of the weather program. In this program, we use Qnetworkaccessmanager to access the network, from a network API to get a city's current weather conditions.
If you look closely, you'll find that even if we don't add any relevant code, Qnetworkaccessmanager's network access does not block the GUI interface. That is to say, even when it comes to network access, our interface can be responsive. In contrast, if you are familiar with Java, you will learn that in Java, in the Socket communication, the interface is blocked by default, when the program for network access operation, the interface can not make any response to our operation. It can be seen that Qnetworkaccessmanager network access by default is asynchronous, Non-blocking. This is a good implementation, and it fits most applications: We certainly want the program interface to always respond to user actions. However, in some cases, we still want to have some synchronized network operations. Typically, a login operation. When we log in, we have to wait for the network to return results before the interface responds: Verify that the system is successfully entered, or that the validation fails. This is the main part of this chapter: how to use Qnetworkaccessmanager for synchronous network access.
When we rerun the previously compiled program, we can look at an operation like this: Because our interface is not blocked, then when we first clicked the Refresh button, immediately switch to the city and then click the Refresh button, you will see the first return of the results flashed. This is because the first time the network request has not been completed, the user sends another request, and Qt displays the return result order of the two requests. This can result in inconsistencies with expectations (such as the first request response being unusually slow for some reason, the second time is very quick, when the second result is better than the first, then it is obvious that the second result will be overwritten when the first result returns. We assume that the user needs to return for a second time, and then an exception will occur.
To resolve this situation, we can lock the interface when there is a network request and not allow the user to do more (the better way is to just lock some buttons rather than the entire interface.) But here's an example of locking the entire interface. Our solution is simple: When Qnetworkaccessmanager makes a request, we enter a new event loop that blocks the operation. Our code example is as follows:
1 2 3 4 5 6 7 8 9 |
void Fetchweather (const QString & cityname) {Qeventloop eventloop; Connect (Networker, & Networker:: Finished, & EventLoop, & Qeventloop:: Quit); Qnetworkreply * reply = NetWorker-> get (QString ("http://api.openweathermap.org/data/2.5/weather?q=%1&mode= Json&units=metric&lang=zh_cn "). Arg |