| 
 Название: Загрузка файлов
 Отправлено: CrossScofield от Февраля 20, 2013,  01:28
 
 Всем доброй ночи. Прошу помощи. Создал я класс для загрузки файлов, на основе стандартного примера http. Но есть одна проблема. После того как я послал команду загрузить файл, я сразу же начинаю его обрабатывать, но файл загружается позже, как будто процесс загрузки работает в отдельном потоке. Как сделать так что бы программа застывала пока загружается файл? Вот код класса:  #include "download.h"#include "ui_authenticationdialog.h"
 download::download(QWidget *parent) :
 QObject()
 {
 g_isComplete=false;
 connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
 this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
 }
 void download::sslErrors(QNetworkReply*,const QList<QSslError> &errors)
 {
 QString errorString;
 foreach (const QSslError &error, errors) {
 if (!errorString.isEmpty())
 errorString += ", ";
 errorString += error.errorString();
 }
 
 if (QMessageBox::warning(0, tr("HTTP"),
 tr("One or more SSL errors has occurred: %1").arg(errorString),
 QMessageBox::Ignore | QMessageBox::Abort) == QMessageBox::Ignore) {
 reply->ignoreSslErrors();
 }
 }
 void download::setInfo(QUrl query, QUrl urlAdress, QString newName){
 queryString = query.toString();
 url = urlAdress;
 fileName = newName;
 }
 bool download::isComplete(){
 return g_isComplete;
 }
 
 void download::httpFinished()
 {
 file->flush();
 file->close();
 QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
 if (reply->error()) {
 file->remove();
 } else if (!redirectionTarget.isNull()) {
 QUrl newUrl = url.resolved(redirectionTarget.toUrl());
 if (QMessageBox::question(0, tr("HTTP"),
 tr("Redirect to %1 ?").arg(newUrl.toString()),
 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
 url = newUrl;
 reply->deleteLater();
 file->open(QIODevice::WriteOnly);
 file->resize(0);
 startRequest(url);
 return;
 }
 } else {
 //file->close();
 }
 
 reply->deleteLater();
 reply = 0;
 delete file;
 file = 0;
 g_isComplete=true;
 }
 
 void download::startRequest(QUrl url)
 {
 QNetworkRequest request(url);
 QByteArray data;
 QList<QNetworkCookie> cookies;
 cookies.append(QNetworkCookie("PHPSESSID", "a0be8t0253m4lvo5hlv20j2ns5"));
 request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");
 request.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(cookies));
 data = queryString.toAscii();
 
 reply = qnam.post(request,data);
 
 connect(reply, SIGNAL(finished()),
 this, SLOT(httpFinished()));
 connect(reply, SIGNAL(readyRead()),
 this, SLOT(httpReadyRead()));
 
 }
 
 void download::slotAuthenticationRequired(QNetworkReply*,QAuthenticator *authenticator)
 {
 QDialog dlg;
 Ui::Dialog ui;
 ui.setupUi(&dlg);
 dlg.adjustSize();
 ui.siteDescription->setText(tr("%1 at %2").arg(authenticator->realm()).arg(url.host()));
 
 // Did the URL have information? Fill the UI
 // this is only relevant if the URL-supplied credentials were wrong
 
 }
 void download::httpReadyRead()
 {
 // this slot gets called every time the QNetworkReply has new data.
 // We read all of its new data and write it into the file.
 // That way we use less RAM than when reading it at the finished()
 // signal of the QNetworkReply
 if (file)
 file->write(reply->readAll());
 }
 void download::startDownload(){
 g_isComplete=false;
 if(fileName.isEmpty() || fileName.isNull() || url.isEmpty() || (!url.isValid())){
 QMessageBox::critical(0,"Error","Name of file or URL is empty or incorrect.");
 return;
 }
 file = new QFile(fileName);
 if (!file->open(QIODevice::WriteOnly)) {
 QMessageBox::information(0, tr("HTTP"),
 tr("Unable to save the file %1: %2.")
 .arg(fileName).arg(file->errorString()));
 delete file;
 file = 0;
 return;
 }
 startRequest(url);
 
 }
 
 
 Название: Re: Загрузка файлов
 Отправлено: Alex Custov от Февраля 20, 2013,  02:10
 
 Крутить локальный QEventLoop. Но это практика порочная. Нужно использовать событийную систему, продолжая обработку загруженных данных уже в слоте по сигналу finished(), не замораживая основную нить. 
 Название: Re: Загрузка файлов
 Отправлено: CrossScofield от Февраля 20, 2013,  12:10
 
 Alex Custov, спасибо за ответ. Идея с eventloop мне понравилась, хоть и понимаю что это не лучшее решение, но использовать весь этот код везде где нужно загрузить файл, для меня роскошь не позволительная, так что только eventloop меня и спасет) 
 Название: Re: Загрузка файлов
 Отправлено: GreatSnake от Февраля 20, 2013,  12:47
 
 Крутить локальный QEventLoop. Но это практика порочная. Нужно использовать событийную систему, продолжая обработку загруженных данных уже в слоте по сигналу finished(), не замораживая основную нить.
 И с чего это вдруг локальный QEventLoop стал порочным ??? И почему встроенный в QCoreApplication QEventLoop менее порочен чем локальный ???
 Название: Re: Загрузка файлов
 Отправлено: CrossScofield от Февраля 20, 2013,  12:55
 
 Только что проверил QEventLoop... великолепно работает. 
 
 |