Как мне использовать QFtp :: put для загрузки файла в Qt C ++? - PullRequest
0 голосов
/ 19 декабря 2011

Я хотел бы использовать QFtp для загрузки текстового файла на FTP-сервер.

Вот мой код:

QFile *file = new QFile("test.txt");
QFtp *ftp = new QFtp();

if(file->open(QIODevice::ReadWrite)) {
    ftp->setTransferMode(QFtp::Active);
    ftp->connectToHost(server);
    ftp->login(name, password);
    ftp->put(file, "test.txt");
    ftp->close();
}

После выполнения этого кода я не вижу ничего на своем ftp-сервере.Когда я просматриваю документацию по QFtp :: put, я вижу, что первым параметром должен быть QIODevice или QByteArray.Как мне это сделать?

Редактировать:
Итак, теперь у меня есть этот код:

//ftp.cpp
QFile *file = new QFile("test.txt");
QFtp *ftp = new QFtp();

this->connect(ftp, SIGNAL(commandStarted(int)), SLOT(ftpCommandStarted(int)));
this->connect(ftp, SIGNAL(commandFinished(int, bool)), SLOT(ftpCommandFinished(int, bool)));  
this->connect(ftp, SIGNAL(done(bool)), SLOT(ftpDone(bool)));
this->connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)), SLOT(ftpDataTransferProgress(qint64, qint64)));
this->connect(ftp, SIGNAL(stateChanged(int)), SLOT(ftpStateChanged(int)));

if(file->open(QIODevice::ReadWrite)) {
    ftp->setTransferMode(QFtp::Active);
    ftp->connectToHost(server);
    ftp->login(name, password);
    ftp->put(file, "test.txt");
    ftp->close();
}

с этими функциями:

//ftp.h
void ftpCommandStarted(int id);
void ftpCommandFinished(int id, bool error);
void ftpDone(bool);
void ftpDataTransferProgress(qint64, qint64);
void ftpStateChanged(int);

//ftp.cpp
void EmailDialog::ftpCommandStarted(int id) {
    this->messageBox("Command Started: " + QString::number(id));
}

void EmailDialog::ftpCommandFinished(int id, bool error) {
    this->messageBox("Command Finished: " + QString::number(id) + " Error: " + (error ? "Error" : "No Error"));
}

void EmailDialog::ftpDone(bool error) {
    this->messageBox("Done " + QString(error ? "Error" : "No Error"));
}

void EmailDialog::ftpDataTransferProgress(qint64 done, qint64 total) {
    this->messageBox("Done: " + QString::number(done) + " Total: " + QString::number(total));
}

void EmailDialog::ftpStateChanged(int state) {
    QString text;
    switch (state) {
        case 0:
            text = "QFtp::Unconnected";
            break;
        case 1:
            text = "QFtp::HostLookup";
            break;
        case 2:
            text = "QFtp::Connecting";
            break;
        case 3:
            text = "QFtp::Connected";
            break;
        case 4:
            text = "QFtp::LoggingIn";
            break;
        case 5:
            text = "QFtp::Closing";
            break;
        default:
            text = "";
            break;
    }
    this->messageBox(text);
}

Однако я не наденуне получить никаких признаков того, что слоты вызываются.У меня не появляется никаких сообщений.Что я тут не так делаю?

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

Фрагмент кода, который у вас есть, выглядит правильно (хотя и не пытался его скомпилировать), поэтому проблема, вероятно, лежит где-то вне этого фрагмента.

В ответ на другой ответ вам не нужно перехватывать сигналы для выполнения кода. Вызов put, close и т. Д. Поставит эти команды в очередь, и они будут выполняться, когда они будут готовы независимо от того, подключены ли вы к сигналам или нет. См. «Подробное описание» в документах . При этом я настоятельно рекомендую подключаться к сигналам, поскольку именно так вы получаете обратную связь для своих пользователей и для отладки.

Что касается того, почему ваш текущий код не работает, наиболее распространенные вопросы, которые я хотел бы задать:

  1. Расширяет ли класс, содержащий объект QFtp, QObject?
  2. Содержит ли ваш заголовочный файл макрос Q_OBJECT?
  3. Перезапускали ли вы qmake после расширения QObject или добавления макроса Q_OBJECT?
  4. Получаете ли вы какие-либо ошибки "сигнал / слот не существует" на вашей консоли? Обычно это означает, что в названии вашего сигнала / слота есть опечатка.
  5. Есть ли в вашем приложении цикл обработки событий? QFtp требует , потому что он ставит свои вызовы в очередь асинхронно. Кроме того, для работы всех сигналов и слотов необходим цикл обработки событий. Вы запускаете цикл обработки событий, вызывая exec для своего QApplication, который обычно находится в main ().
  6. Есть ли у вас правила брандмауэра, блокирующие вашу передачу ftp? Вам может понадобиться использовать QFtp :: Passive.

Это основные проблемы, о которых я могу думать. Удачи!

1 голос
/ 19 декабря 2011

Класс QFtp работает асинхронно для передачи данных.Таким образом, последовательный вызов функций connectcToHost, put, error, currentCommand и close фактически никогда не выполнит ни одну из команд.Что вам нужно сделать, это написать класс, чтобы вы могли использовать сигналы и слоты.Поймать сигналы после начала передачи является ключом.Пример, приведенный в подробном описании QFtp, дает некоторые пояснения к вашей проблеме /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...