Evgenii Legotckoi
Evgenii Legotckoi06 червня 2017 р. 12:48

Qt/C++ - Підручник 066. Завантаження файлів на FTP-сервер

Для роботи з мережею 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/

Скачати проект

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:50бали,
  • Рейтинг балів-4
m
  • molni99
  • 26 жовтня 2024 р. 01:37

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80бали,
  • Рейтинг балів4
m
  • molni99
  • 26 жовтня 2024 р. 01:29

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:20бали,
  • Рейтинг балів-10
Останні коментарі
ИМ
Игорь Максимов22 листопада 2024 р. 11:51
Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii Legotckoi31 жовтня 2024 р. 14:37
Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZE19 жовтня 2024 р. 08:19
Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь Максимов05 жовтня 2024 р. 07:51
Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas505 липня 2024 р. 11:02
QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Тепер обговоріть на форумі
Evgenii Legotckoi
Evgenii Legotckoi24 червня 2024 р. 15:11
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey115 листопада 2024 р. 06:04
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProject04 червня 2022 р. 03:49
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9Anonim25 жовтня 2024 р. 09:10
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Слідкуйте за нами в соціальних мережах