2015-03-24 2 views
1

Je souhaite utiliser QFtp pour la première fois et faire beaucoup de recherches sur Google pour savoir comment l'utiliser. Ceci, entre autres est un exemple typique:Qt, QCoreApplication et QFtp

#include <QCoreApplication> 
#include <QFtp> 
#include <QFile> 

int main(int argc, char ** argv) 
{ 
    QCoreApplication app(argc, argv); 

    QFile *file = new QFile("C:\\Devel\\THP\\tmp\\test.txt"); 
    file->open(QIODevice::ReadWrite); 

    QFtp *ftp = new QFtp(); 

    ftp->setTransferMode(QFtp::Active); 
    ftp->connectToHost("ftp.trolltech.com"); 
    ftp->login();       
    ftp->cd("qt");      
    ftp->get("INSTALL",file);    
    ftp->close(); 

    QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit())); 

    int ret = app.exec(); 

    delete ftp; 
    delete file; 

    return ret; 
} 

La question:

Pour autant que je compris, l'application QCoreApplication est nécessaire pour gérer le signal « fait », exprimés lors de la finalisation de ftp-get. Maintenant, le ftp->get est appelé avant la connexion et même avant que le gestionnaire de l'application soit en cours d'exécution (app.exec() est appelé par la suite). Que se passe-t-il si le transfert de fichier est déjà terminé avant l'instruction "connect"? En fait, cela n'arrivera pas, mais je pourrais mettre un retard artificiel de, disons 1 minute entre ftp->close() et le connecter (...). Pendant ce temps, le ftp get sera sûrement fini. Ce qui se passerait?

+1

Si le ftp est fait avant le début de la boucle d'événements, votre application ne se fermera pas et vous devrez tuer son processus. – vahancho

+0

'QFtp' a besoin d'une boucle d'événement en cours pour traiter les commandes. Vous pouvez donc attendre 10 000 ans avant l'instruction 'connect' et cela ne ferait aucune différence puisque les commandes que vous dites à' QFtp' ne seront pas exécutées avant d'appeler 'app.exec();' – thuga

Répondre

0

Notez que QFtp n'est réellement destiné qu'aux applications Qt héritées et qu'il est maintenant suggéré d'utiliser QNetworkAccessManager et QNetworkReply à la place, comme indiqué dans le Qt documentation. Cela étant dit, avec votre appel de connexion étant positionné après la connexion au site FTP et la récupération du fichier, si le fichier est téléchargé en premier, le signal «quitter» ne serait jamais atteint. Si vous faites la connexion juste après la création de l'objet QFtp, alors ce ne sera pas un problème: -

QFtp *ftp = new QFtp(); 
QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit())); 

Cela garantit que la fente « quit » sera appelée lorsque l'objet QFtp émet le signal « fait » .

QFtp *ftp = new QFtp(); 
QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit())); 

ftp->setTransferMode(QFtp::Active); 
ftp->connectToHost("ftp.trolltech.com"); 
ftp->login();       
ftp->cd("qt");      
ftp->get("INSTALL",file);    
ftp->close(); 

int ret = app.exec(); 

En réalité cependant, j'attendre la connexion dans votre exemple compléterait avant que la machine ait eu le temps de négocier une connexion à un autre serveur, connectez-vous et commencer le téléchargement du fichier.

+0

Veuillez noter que Qt ne gère pas les signaux/slots ** avant que ** 'app.exec();' ait appelé pour démarrer la boucle d'événement. – vahancho

+0

@vahancho, oui c'est pourquoi je suggère d'utiliser le QTimer avec un timeout zéro pour m'assurer que le processus FTP se produira après le début de la boucle d'événement principal, ou est-ce qu'il me manque quelque chose ici? – TheDarkKnight

+1

['QFtp' utilise en interne' QTimer :: singleshot' (https://qt.gitorious.org/qt/qt/source/d36f83d319823e9c9a4fd939b12e17223413474e:src/network/access/qftp.cpp#L1336) pour chaque commande. QFtp ne fera rien jusqu'à ce que la boucle d'événement soit démarrée. Donc, retarder la création de 'QFtp' et ses commandes est inutile. – thuga