2015-03-24 16 views
1

Я хочу использовать QFtp в первый раз и много разобраться, чтобы узнать, как его использовать. Это, среди прочего, является типичным примером:Qt, QCoreApplication и 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; 
} 

Вопрос:

Насколько я понял, приложение QCoreApplication нужно обрабатывать «сделано» сигнал, emmited после завершения работы FTP-получить. Теперь, ftp->get вызывается перед подключением и даже до того, как обработчик приложения вообще запущен (app.exec() вызывается потом).

Что происходит, если передача файлов завершена уже до утверждения «connect»? На самом деле этого не произойдет, но я могу установить искусственную задержку, скажем, 1 минута между ftp->close() и подключением (...). За это время, ftp get, безусловно, будет закончен. Что случилось бы?

+1

Если ftp выполняется до того, как цикл событий запущен, приложение не выйдет, и вам придется убить его процесс. – vahancho

+0

Для обработки команд 'QFtp' нужен цикл выполнения событий. Таким образом, вы можете подождать 10 000 лет до утверждения 'connect', и не имеет значения, поскольку команды, которые вы укажете' QFtp' для выполнения, не будут выполнены до вызова 'app.exec();' – thuga

ответ

0

Обратите внимание, что QFtp действительно предназначен только для устаревших приложений Qt, и теперь предлагается использовать QNetworkAccessManager и QNetworkReply, как указано в Qt documentation.

С учетом того, что после подключения к FTP-сайту и извлечения файла он должен быть загружен, если файл будет загружен первым, сигнал «выйти» никогда не будет достигнут. Если вы делаете подключение сразу после создания объекта QFtp, то это не будет проблемой: -

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

Это гарантирует, что «бросить курить» слот будет вызываться, когда объект QFtp излучает «сделано» сигнал ,

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

На самом же деле, я бы ожидать подключения в вашем примере будет завершить, прежде чем машина успела обсудить соединение с другим сервером, логин и начать загрузку файла.

+0

Обратите внимание, что Qt не будет обрабатывать сигналы/слоты ** до ** 'app.exec();' вызывается для запуска цикла событий. – vahancho

+0

@vahancho, да, поэтому я предлагаю использовать QTimer с нулевым таймаутом, чтобы гарантировать, что процесс FTP происходит после того, как начался цикл основного события, или я чего-то здесь не вижу? – TheDarkKnight

+1

['QFtp' использует' QTimer :: singleshot' внутренне] (https://qt.gitorious.org/qt/qt/source/d36f83d319823e9c9a4fd939b12e17223413474e:src/network/access/qftp.cpp#L1336) для каждой команды. 'QFtp' ничего не сделает, пока не запустится цикл событий. Поэтому отложить создание 'QFtp' и его команд не нужно. – thuga