- 1. Структура проекта
- 2. widget.h
- 3. widget.cpp
- 4. Итог
Для работы с сетью в Qt 5 используется модуль Network , а для передачи данных по сети можно активно использовать класс QNetworkAccessManager , если Вы не создаёте свой собственный протокол для передачи данных. Но для работы с FTP достаточно использования QNetworkAccessManager , с которым мы уже работали при реализации скачивания файла с сайта .
Напишем небольшую программу, которая будет загружать на сервер произвольный файл, который мы будем выбирать на нашем ПК с помощью диалога выбора файла. Также будет показан прогресс загрузки файла на FTP сервер.
Для этого в окне приложения будет присутствовать кнопка для открытия диалога выбора файла. QLineEdit, в котором будет отображаться путь к файлу. QLineEdit, в который мы будем вводить адрес, по которому будет производиться загрузка файла. Кнопка запуска загрузки, а также прогресс бар, который покажет прогресс загрузки файла на сервер.
Структура проекта
- UploadFile.pro - профайл проекта.
- main.cpp - файл функции main.
- widget.h - заголовочный файл окна приложения.
- widget.cpp - файл реализации окна приложения.
- widget.ui - файл формы окна приложения.
В профайл проекта необходимо добавить модуль network, чтобы работать с QNetworkAccessManger`ом.
QT += network
Файл main.cpp создаётся по умолчанию и изменению не подвергается. В графическом дизайнере будет создана форма окна, которое было показано в начале статьи.
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QNetworkAccessManager> #include <QNetworkReply> #include <QString> #include <QFile> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void on_selectFileButton_clicked(); // Слот для вызова диалога выбора файла void on_uploadButton_clicked(); // Слот для запуска загрузки void uploadFinished(QNetworkReply *reply); // Слот окончания загрузки void uploadProgress(qint64 bytesSent, qint64 bytesTotal); // Слот прогресса загрузки private: Ui::Widget *ui; QNetworkAccessManager *m_manager; QString m_fileName; // Файл обязательно необходимо сохранять в куче // Если создавать объект файла в стеке, то программа будет крашиться. QFile *m_file; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" #include <QFileDialog> #include <QUrl> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); m_manager = new QNetworkAccessManager(this); connect(m_manager, &QNetworkAccessManager::finished, this, &Widget::uploadFinished); } Widget::~Widget() { delete ui; } void Widget::on_selectFileButton_clicked() { m_fileName = QFileDialog::getOpenFileName(this, "Get Any File"); ui->fileNameLineEdit->setText(m_fileName); } void Widget::on_uploadButton_clicked() { // Создаём объект файла при запуске загрузки m_file = new QFile(m_fileName); // Далее требуется информация об имени файла // Путь загрузки на сервер должен выглядеть следующим образом // ftp://example.com/path/to/file/filename.txt // То есть указываем протокол -> ftp // Сервер -> example.com // Путь, где будет располагаться файла -> path/to/file/ // И имя самого файла, который берём из QFileInfo -> filename.txt QFileInfo fileInfo(*m_file); QUrl url(ui->uploadUrlLineEdit->text() + fileInfo.fileName()); url.setUserName("login"); // Устанавливаем login url.setPassword("password"); // Устанавливаем пароль url.setPort(21); // Порт протокола, по которому будем работать if (m_file->open(QIODevice::ReadOnly)) { // Запускаем загрузку QNetworkReply *reply = m_manager->put(QNetworkRequest(url), m_file); // и коннектимся к сигналу прогресса загрузки connect(reply, &QNetworkReply::uploadProgress, this, &Widget::uploadProgress); } } void Widget::uploadFinished(QNetworkReply *reply) { // Если загрузка прошла без ошибок if (!reply->error()) { // то закрываем файл m_file->close(); m_file->deleteLater(); // Удаляем объект файла reply->deleteLater(); // Удаляем объект ответа } } void Widget::uploadProgress(qint64 bytesSent, qint64 bytesTotal) { // отображаем прогресс загрузки ui->progressBar->setValue(100 * bytesSent/bytesTotal); }
Итог
В результате получится загрузить выбранный файл на FTP сервер (хотя конечно в сети на форумах и есть сообщения о том, что не все FTP-сервера работают хорошо, но это уже нюансы).
Также отмечу, что в данной программе мало проверок и валидаций, поэтому вводите путь к серверу так, чтобы строка была закрыта слешем. Например:
ftp://example.com/path/to/file/