Класс QFtp работает асинхронно. Когда мы вызываем такие функции, как get() или put(), управление сразу же возвращается к нам, а пересылка данных осуществляется после передачи управления обратно в цикл обработки событий Qt. Это обеспечивает работоспособность интерфейса пользователя во время выполнения команд FTP.

Мы начнем с примера чтения одного файла с помощью функции get(). В этом примере создается консольное приложение с именем ftpget, которое скачивает удаленный файл, указанный в командной строке. Давайте начнем с функции main():

01 int main(int argc, char *argv[])

02 {

03 QCoreApplication app(argc, argv);

04 QStringList args = app.arguments();

05 if (args.count() != 2) {

06 cerr << "Usage: ftpget url" << endl << "Example:" << endl

07 << " ftpget ftp://ftp.trolltech.com/mirrors" << endl;

08 return 1;

09 }

10 FtpGet getter;

11 if (!getter.getFile(QUrl(args[1])))

12 return 1;

13 QObject::connect(&getter, SIGNAL(done()), &app, SLOT(quit()));

14 return app.exec();

15 }

Мы создаем объект класса QCoreApplication, а не его подкласса QApplication, чтобы избежать сборки с библиотекой QtGui. Функция QCoreApplication::arguments() возвращает аргументы командной строки в виде списка QStringList, первым элементом которого является имя вызванной программы, а все специфичные для Qt аргументы, такие как —style, удаляются. Центральными моментами в функции main() являются конструирование объекта FtpGet и вызов функции getFile(). Если этот вызов оказывается успешным, мы позволяем циклу событий выполняться до тех пор, пока файл не будет полностью скачан.

Всю работу делает подкласс FtpGet, который определяется следующим образом:

01 class FtpGet : public QObject

02 {

03 Q_OBJECT

04 public:

05 FtpGet(QObject *parent = 0);

06 bool getFile(const QUrl &url);

07 signals:

08 void done();

09 private slots:

10 void ftpDone(bool error);

11 private:

12 QFtp ftp;

13 QFile file;

14 …

15 };

Класс имеет открытую функцию getFile(), которая считывает файл по указанному адресу URL. Класс QUrl имеет высокоуровневый интерфейс для извлечения различных частей URL, таких как имя файла, путь, протокол и порт.

Класс FtpGet имеет закрытый слот ftpDone(bool), который вызывается после окончания операции пересылки файла, и сигнал done(), который генерируется при завершении скачивания файла. Этот класс имеет также две закрытые переменные. Переменная ftp имеет тип QFtp и инкапсулирует соединение с сервером FTP; переменная file используется для записи скачанного из сети файла на диск.

01 FtpGet::FtpGet(QObject *parent)

02 : QObject(parent)

03 {

04 connect(&ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));

05 }

В конструкторе мы подсоединяем сигнал QFtp::done(bool) к нашему закрытому слоту ftpDone(bool). QFtp генерирует сигнал done(bool) после завершения обработки всех запросов. Параметр типа bool показывает, возникла ошибка или нет.

01 bool FtpGet::getFile(const QUrl &url)

02 {

03 if (!url.isValid()) {

04 cerr << "Error: Invalid URL" << endl;

05 return false;

06 }

07 if (url.scheme() != "ftp") {

08 cerr << "Error: URL must start with 'ftp:'" << endl;

09 return false;

10 }

11 if (url.path().isEmpty()) {

12 cerr << "Error: URL has no path" << endl;

13 return false;

14 }

15 QString localFileName = QFileInfo(url.path()).fileName();

Перейти на страницу:

Похожие книги