1

I want to use QFtp for the first time and googled a lot to find out how it should be used. This, among others is a typical example:

#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;
}

The question:

As far as I understood, the QCoreApplication app is needed to handle the "done" signal, emmited upon finalization of ftp-get. Now, the ftp->get is called before the connect and even before the app handler is running at all (app.exec() is called afterwards).

What happens, if the file transfer has completed already before the "connect" statement? In fact, that will not happen, but I could put an artificial delay of, say 1 minute between ftp->close() and the connect(...). During this time, the ftp get will surely be finished. What would happen?

IAmInPLS
  • 4,051
  • 4
  • 24
  • 57
MichaelW
  • 1,328
  • 1
  • 15
  • 32
  • 1
    If the ftp is done before the event loop has started your application will not exit and you will have to kill its process. – vahancho Mar 24 '15 at 13:26
  • `QFtp` needs a running event loop in order to process commands. So you can wait for 10 000 years before the `connect` statement and it would make no difference as the commands you tell `QFtp` to execute won't be executed before you call `app.exec();` – thuga Mar 25 '15 at 08:06

1 Answers1

0

Note that QFtp is really only meant for legacy Qt applications and it is now suggested that QNetworkAccessManager and QNetworkReply are used instead, as detailed in the Qt documentation.

That being said, with your connect call being positioned after the connection to the FTP site and retrieving of the file, should the file be downloaded first, the 'quit' signal would never be reached. If you make the connection straight after creating the QFtp object, then this won't be an issue: -

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

This guarantees that the 'quit' slot will be called when the QFtp object emits the 'done' signal.

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();

In reality though, I would expect the connect in your example would complete before the machine had time to negotiate a connection to another server, login and start the download of the file.

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • Please note that Qt will not handle signals/slots **before** `app.exec();` has called to start the event loop. – vahancho Mar 24 '15 at 13:38
  • @vahancho, yes that is why I suggest using the QTimer with a zero timeout to ensure the FTP process occurs after the main event loop has started, or am I missing something here? – TheDarkKnight Mar 24 '15 at 14:19
  • 1
    [`QFtp` uses `QTimer::singleshot` internally](https://qt.gitorious.org/qt/qt/source/d36f83d319823e9c9a4fd939b12e17223413474e:src/network/access/qftp.cpp#L1336) for every command. `QFtp` will do nothing until the event loop is started. So delaying the creation of `QFtp` and its commands is unnecessary. – thuga Mar 25 '15 at 08:12
  • @thuga, good point and thanks for pointing it out. I've updated the answer accordingly. – TheDarkKnight Mar 25 '15 at 09:19