2012-05-08 4 views
1

Я новичок в QT и столкнулся с следующей проблемой.Загрузка файла по http

Загрузка возвращает пустой файл:

QFile file("book.gif"); 
QHttp http; 
if (file.open(QIODevice::WriteOnly)) 
{ 
    http.setHost("www.geocities.com"); 
    http.get("/mslerm/images/qtbook.gif", &file); 
    http.close(); 
    file.close(); 
} 

Но если перед закрытием MessageBox HTTP вызова - все работает отлично:

QFile file("book.gif"); 
QHttp http; 
if (file.open(QIODevice::WriteOnly)) 
{ 
    http.setHost("www.geocities.com"); 
    http.get("/mslerm/images/qtbook.gif", &file); 
    QMessageBox msgBox; 
    msgBox.setText(http.errorString()); 
    msgBox.exec(); 
    http.close(); 
    file.close(); 
} 

Любые идеи?

ответ

4

Проблема заключается в том, что прибудет() метода не является блокировкой, как указано в самой документации: Qhttp.get

Один из способов, чтобы продолжить это подключить QHttp :: dataReadProgressсигнала с слот вы разрабатываете, где обрабатываете полученные данные с объекта QHttp. помнить также, что оба QHttp и QFtp классы теперь осуждается и предложил классы для использования являются:

QNetworkAccessManager
QNetworkRequest
QNetworkReply

+1

Спасибо за подробный ответ – mmatviyiv

3

Вы должны подключить некоторый обратный вызов к завершенному сигналу QHttp и закрыть обработчик файла. Когда вы создаете окно сообщения, время его появления и закрытие его, вероятно, достаточно для завершения загрузки, а затем вы правильно закрываете обработчик файлов. Ключ в том, что метод QMessageDialog :: exec является синхронным.

0

окно сообщений закручивает цикл событий в Exec() и позволяет QHttp-х асинхронная обработка. Цикл событий должен иметь возможность запускать между запуском передачи и ожиданием каких-либо результатов.

В идеале вы должны начать передачу и обработать результаты в слоте, подключенном к сигналу requestFinished(...) QHttp. После того, как передача началась, ваш код должен вернуться в цикл событий.

В качестве быстрого взлома вы можете вызывать QCoreApplication::processEvents(QEventLoop::AllEvents, time), где время - это максимальное количество миллисекунд, которое вы ожидаете от своего переноса http. Это будет считаться плохим стилем и имеет негативные последствия. Во-первых, код, который запускает передачу, может быть повторно введен - скажем, если вы начнете передачу в слот с нажатием кнопки, и пользователь снова щелкнет его до передачи.

Вы должны использовать асинхронный стиль программирования, основанный на событиях, где у вас есть цепочка функций запроса/ответа: функции запроса запускают вещи, которые могут занять время, а функции ответа обрабатывают результаты. Это может показаться утомительным, но это единственный способ создать отзывчивые приложения. Такой код обычно будет находиться в QObject, и если вся обработка выполняется путем обработки событий или соединениями с сигналом/слотом (но не прямым вызовом слотов!), Он может быть тривиально перемещен в другой поток для дальнейшего повышения производительности и уменьшить влияние пауз в графическом интерфейсе смешанной родословной.

Смежные вопросы