- 1. Структура проекту
- 2. віджет.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 створюється за замовчуванням та не змінюється. У графічному дизайнері буде створено форму вікна, яке було показано на початку статті.
віджет.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/