IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
FAQ Qt FAQ Qt Creator FAQ PyQt & PySide

FAQ Qt

FAQ QtConsultez toutes les FAQ

Nombre d'auteurs : 26, nombre de questions : 298, dernière mise à jour : 15 juin 2021 

 
OuvrirSommaireModulesQt NetworkGestionnaire d'accès

Qt 4.4 nous fournit une alternative à QHttp et à QFtp : QNetworkAccessManager. Ce gestionnaire permet d'utiliser d'autres protocoles (HTTPS, par exemple), sans devoir changer autre chose que les URL, dans son code.

L'architecture de ce nouveau système est tout à fait différente : il y a un objet-maître, un QNetworkAccessManager, le gestionnaire. Il gère, entre autres, le cache, le proxy, les paramètres par défaut... C'est lui qui envoie les signaux de fin de téléchargement, aussi.

On ne crée plus un objet indépendant par requête : on instancie un manager, puis on lui demande de récupérer un fichier, grâce à son URL. Ce fichier est demandé sous la forme d'une requête QNetworkRequest. Cette requête ne contient pas que l'URL : elle contient aussi les en-têtes supplémentaires à envoyer au serveur, la configuration SSL...

Une fois que le fichier a été téléchargé, il est renvoyé, sous la forme d'une réponse, un QNetworkReply. Il s'agit d'un dérivé de QIODevice, et peut donc s'utiliser de la même manière. Il peut être envoyé en tant que paramètre du signal finished() du gestionnaire ou bien dès que l'ordre de téléchargement du fichier a été donné. Il est cependant déconseillé de procéder de la sorte, car le téléchargement n'aura probablement pas encore pu être initié.

 
Sélectionnez
QNetworkAccessManager * manager = new QNetworkAccessManager;
QNetworkReply * reply = manager->get("http://qt.developpez.com");

Dès que le gestionnaire aura envoyé le signal finished(), la réponse contiendra le contenu du fichier.

Notez que l'on aurait pu aussi procéder de cette manière.

 
Sélectionnez
QNetworkAccessManager * manager = new QNetworkAccessManager;
manager->get("http://qt.developpez.com");

En effet, le gestionnaire enverra le signal finished() avec un argument, un pointeur vers la réponse.

Mis à jour le 7 mai 2012  par Thibaut Cuvelier

Le protocole HTTP est principalement prévu pour la récupération de données (par les méthodes GET et HEAD), mais il peut aussi envoyer des données (par les méthodes POST et PUT). Il faut utiliser les méthodes du gestionnaire réseau homonymes à la méthode.

Pour l'envoi, elles prennent deux paramètres : une requête QNetworkRequest et des données QByteArray.

 
Sélectionnez
QNetworkAccessManager * manager = new QNetworkAccessManager;

QUrl url ("http://qt.developpez.com");
QNetworkRequest request (url);
QByteArray data = "data";

manager->post(request, data);
Mis à jour le 7 mai 2012  par Thibaut Cuvelier

Qt nous fournit une classe, QNetworkProxy, qui représente un proxy. Vous pouvez en spécifier un à votre gestionnaire QNetworkAccessManager grâce à sa méthode setProxy(). Ce proxy peut être aussi utilisé par d'autres classes, plus anciennes, à chaque fois grâce à la méthode setProxy() : QHttp, QFtp, QAbstractSocket, QTcpSocket, QUdpSocket, QTcpServer...

Voici un exemple de création de proxy, assez explicite.

 
Sélectionnez
QNetworkProxy proxy;
proxy.setType(QNetworkProxy::Socks5Proxy);
proxy.setHostName("proxy.exemple.com");
proxy.setPort(1080);
proxy.setUser("username");
proxy.setPassword("password");

Le type du proxy est choisi dans l'énumération QNetworkProxy::ProxyType, que voici.

 
Sélectionnez
enum ProxyType { NoProxy, DefaultProxy, Socks5Proxy, HttpProxy,
                 HttpCachingProxy, FtpCachingProxy              }

DefaultProxy oblige l'utilisation du proxy par défaut.

Maintenant, nous allons voir comment demander à un objet de passer par un proxy. Nous considérerons à la suite de l'exemple de création d'un proxy.

 
Sélectionnez
QNetworkAccessManager manager;
manager->setProxy (proxy);
 
Sélectionnez
QWebView * view = new QWebView;
view->page()->networkAccessManager()->setProxy(proxy);
Mis à jour le 7 mai 2012  par Thibaut Cuvelier

Lien : Comment définir un proxy par défaut ?

La fonction statique QNetworkProxy::setApplicationProxy() est utilisée pour définir le proxy par défaut de l'application. Il sera utilisé par défaut dans l'application, mais il pourra être remplacé pour tous les objets en utilisant d'autres méthodes.

On peut aussi récupérer ce proxy par défaut grâce à la fonction statique QNetworkProxy::applicationProxy().

 
Sélectionnez
// QNetworkProxy::applicationProxy() == QNetworkProxy()
QNetworkProxy::setApplicationProxy (proxy);
// QNetworkProxy::applicationProxy() == proxy
Mis à jour le 4 avril 2010  par Thibaut Cuvelier

Lien : Comment utiliser un proxy ?

Le gestionnaire de requête QNetworkAccessManager permet de télécharger des fichiers à l'aide de la méthode get.

Il est également possible de suivre l'évolution du téléchargement pour, par exemple, l'afficher dans une barre de progression. Il est nécessaire de connecter le signal downloadProgress à un slot à redéfinir.

 
Sélectionnez
QNetworkAccessManager * manager = new QNetworkAccessManager;
QNetworkReply * reply = manager->get(QNetworkRequest(QUrl("http://qt.developpez.com/faq/images/FAQ-Qt.gif")));
connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(requestDownloadProgress(qint64, qint64)));

// Le slot de réception

void requestDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
    qint64 pourcent = (bytesReceived / bytesTotal) * 100;
}
Mis à jour le 7 mai 2012  par Jonathan Courtois

Lien : Comment fonctionne le système de gestionnaire d'accès ?

QtNetwork et QtWebkit sont deux modules permettant chacun de récupérer un fichier de l'Internet, comme des pages Web. QtNetwork fournit la classe QNetworkReply, que nous traiterons, et QtWebkit, QWebFrame. QHttp étant obsolète, son cas ne sera pas traité ici.

Comme QNetworkReply hérite de QIODevice, il possède la fonction readAll(), qui permettra, dans l'exemple qui suit, de récupérer ce qui est souhaité, balises HTML comprises :

 
Sélectionnez
QNetworkAccessManager *manager = new QNetworkAccessManager;
manager->get(QNetworkRequest(QUrl("http://qt.developpez.com/faq/")));
connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(result(QNetworkReply *)));

void Classe::result(QNetworkReply *reply)
{
    QString source = reply->readAll();
    doSomething(source);
}

Cette solution ne prend pas en compte les redirections !

La seconde solution, avec QWebFrame, est très pratique car elle permet, en plus de gérer les redirections, de récupérer la source de la page sous deux formats avec les fonctions toHtml(), qui retourne la source avec les balises HTML, et toPlainText(), qui retourne la source sans les balises HTML.

 
Sélectionnez
view = new QWebView;
view->load(QUrl("http://qt.developpez.com/faq/"));
connect(view, SIGNAL(loadFinished(bool)), this, SLOT(result(bool)));

void Classe::result(bool)
{
    QString html = view->page()->currentFrame()->toHtml();
    QString plainText = view->page()->currentFrame()->toPlainText();
    doSomething(html, plainText);
}

Si on décomposait le code de la fonction result(bool), située ci-dessus, on aurait ceci :

 
Sélectionnez
void Classe::result(bool)
{
    QWebPage *page = view->page();
    QWebFrame *frame = page->currentFrame();
    QString html = frame->toHtml();
    QString plainText = frame->toPlainText();
    doSomething(html, plainText);
}
Mis à jour le 7 mai 2012  par Louis du Verdier

Lorsque l'on souhaite afficher une ressource volumineuse n'étant pas située en local (par exemple, une image), on aime assez pouvoir la mettre en cache pour éviter qu'il y ait de multiples téléchargements ralentissant l'application.

QNetworkAccessManager possède une fonction setCache(), prenant pour argument une classe dérivée de QAbstractNetworkCache, qui permet de définir un cache pour toutes les requêtes effectuées par le gestionnaire d'accès.

Voici un exemple d'utilisation de la fonction setCache() avec une instance de QNetworkDiskCache, classe dérivée de QAbstractNetworkCache qui met à disposition un cache assez basique mais simple d'utilisation :

 
Sélectionnez
// Création d'une instance de QNetworkAccessManager :
QNetworkAccessManager *manager = new QNetworkAccessManager(parent);
// Création d'une instance de QNetworkDiskCache :
QNetworkDiskCache *cache = new QNetworkDiskCache(manager);
// L'emplacement où les fichiers de cache seront écrits :
cache->setCacheDirectory(QDesktopServices::storageLocation(QDesktopServices::CacheLocation));
// Le cache accepte jusqu'à 10Mo :
cache->setMaximumCacheSize(10 * 1024 * 1024);
// On définit le cache du manager à notre objet cache :
manager->setCache(cache);

Cela fait, on utilise le gestionnaire d'accès en précisant que l'on souhaite utiliser le cache, dans la mesure du possible :

 
Sélectionnez
// On connecte le signal finished() du gestionnaire d'accès à la méthode networkReplyFinished() de something :
QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), something, SLOT(networkReplyFinished(QNetworkReply*)));
// On crée une requête vers une image :
QNetworkRequest request(QUrl("http://qt.developpez.com/faq/images/FAQ-Qt.gif"));
// On définit l'attribut CacheLoadControlAttribute à PreferCache
// pour demander à ce que le cache soit utilisé si disponible :
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
// On envoie une requête pour récupérer l'image :
manager->get(request);
 
// ...
 
void MyClass::networkReplyFinished(QNetworkReply *reply)
{
    // Affiche true si l'image a été chargée depuis le cache, sinon false :
    qDebug() << reply->attribute(QNetworkRequest::SourceIsFromCacheAttribute).toBool();
}

Lors de la première exécution de l'application, l'image est chargée depuis l'extérieur. Lors des lancements suivants, elle ne charge plus l'image depuis l'url spécifiée mais depuis le cache.

QNetworkDiskCache est l'unique classe fournie par Qt qui permette de mettre en place un cache. Pour créer son propre système de cache, il suffit de créer une classe dérivée de la classe abstraite QAbstractNetworkCache, d'implémenter ses fonctions et d'utiliser setCache() avec.

Créé le 10 septembre 2011  par Louis du Verdier

Depuis un objet QNetworkReply obtenu du gestionnaire d'accès, il est possible d'arrêter la connexion qui en dépend. Évidemment, il est inutile de récupérer le QNetworkReply envoyé par le signal finished() de QNetworkAccessManager : si le signal est envoyé, c'est que le téléchargement est achevé et qu'il n'est plus possible de l'arrêter.

Vous pouvez utiliser la méthode abort() si vous désirez arrêter absolument toute activité de la réponse : cette méthode arrête tout, téléchargement ou téléversement. Elle finit toute connexion réseau.

Il existe aussi la méthode close(), qui prépare le périphérique à la lecture : les données non lues sont perdues mais les connexions réseau ne s'arrêtent pas tant qu'elles ne sont pas achevées. En particulier, un téléversement en cours ne sera pas arrêté.

 
Sélectionnez
QNetworkAccessManager * manager = new QNetworkAccessManager();
QNetworkReply * reply = manager->get("http://qt.developpez.com");

reply->close();
reply->readAll(); // Cet appel ne renverra pas tout le contenu du fichier, juste ce qui aura été téléchargé, même s'il continue à être téléchargé

reply->abort();
reply->readAll(); // Cet appel ne renverra pas tout le contenu du fichier, juste ce qui aura été téléchargé mais le fichier ne continuera pas à être téléchargé
Créé le 7 mai 2012  par Thibaut Cuvelier

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 - 2017 Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.