31 (30.12.2010 17:44:30 отредактировано XRevan86)

Всё, я перехожу на ООП.
Ещё раз спасибо voral и Civil smile. Желаю вам много радости и конца света в Новом Году!

voral
Да... в Вашем коде 0 Бит получается ag.

32

Darth Revan пишет:

Всё, я перехожу на ООП.
Ещё раз спасибо voral и Civil smile. Желаю вам много радости и конца света в Новом Году!

voral
Да... в Вашем коде 0 Бит получается ag.

странно у меня скачалась вся страниуа

То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me".
GNU/Linux Debian

33

main.cpp:

#include <iostream>
#include <cstdlib>
#include <string>
#include <QApplication>
#include <QDir>

#include "functions.h"

QString CD = PChar2QString("");

int main(int ParamCount, char* ParamStr[])
{
    QApplication Application(ParamCount, ParamStr);
    QURLDownloadToFile DownloadFile;
    QConfigFile ConfigFile;
    CD = Application.applicationDirPath();
    ConfigFile.Save(CD + QDir::separator() + PChar2QString("hello.ini"), PChar2QString("Main"), PChar2QString("DefaultValue"),
                    PChar2QString("HelloWorld"));
    DownloadFile.Initial(PChar2QString("http://www.google.ru/images/srpr/nav_logo27.png"), PChar2QString("google.png"));
    return 0;
}

functions.cpp:

#include <QtCore>
#include <QObject>
#include <QDir>
#include <QtNetwork>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>

#include "functions.h"

QString PChar2QString(const char* PChar)
{
    return QString("%1").arg(PChar);
}

char* QString2PChar(const QString String)
{
    QByteArray Result = String.toAscii();
    return Result.data();
}

QURLDownloadToFile::QURLDownloadToFile(QObject* parent): QObject(parent)
{
}

void QURLDownloadToFile::startRequest(QUrl URL)
{
    Reply = qnam.get(QNetworkRequest(URL));
    connect(Reply, SIGNAL(finished()),
            this, SLOT(httpFinished()));
    connect(Reply, SIGNAL(readyRead()),
            this, SLOT(httpReadyRead()));
}

void QURLDownloadToFile::Initial(QString StringURL, QString FileName)
{
    URL.setUrl(StringURL);
    if ( FileName == PChar2QString("") ) {
      QFileInfo fileInfo(URL.path());
      FileName = fileInfo.fileName();
    }
    if ( QFile::exists(FileName) ) {
      File->remove();
    }

    File = new QFile(FileName);
    if ( !File->open(QIODevice::WriteOnly) ) {
        delete File;
        File = 0;
        return;
    }
    httpRequestAborted = false;
    startRequest(URL);
}

void QURLDownloadToFile::httpFinished()
{
    File->flush();
    File->close();
    Reply->deleteLater();
    Reply = 0;
    delete File;
    File = 0;
}

void QURLDownloadToFile::httpReadyRead()
{
    if ( File )
        File->write( Reply->readAll() );
}

QConfigFile::QConfigFile(QObject *parent): QObject(parent)
{
}

QString QConfigFile::Read(const QString FileName, const QString Section, const QString Value,
                             const QString Default)
{
    IniFile = FileName;
    QSettings Settings(IniFile, QSettings::IniFormat);
    Settings.beginGroup(Section);
    Result = Settings.value(Value, "").toString();
    if ( Result == "" )
        Result = Default;
    Settings.endGroup();
    return Result;
}

void QConfigFile::Save(const QString FileName, const QString Section, const QString Value, const QString InValue)
{
    IniFile = FileName;
    QSettings Settings(IniFile, QSettings::IniFormat);
    Settings.beginGroup(Section);
    Settings.setValue(Value, InValue);
    Settings.endGroup();
}

functions.h:

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QUrl>

QString PChar2QString(const char* PChar);
char* QString2PChar(const QString String);

QT_BEGIN_NAMESPACE
class QFile;
class QNetworkReply;
class QNetworkRequest;
QT_END_NAMESPACE

class QURLDownloadToFile: public QObject
{
    Q_OBJECT

public:
    QURLDownloadToFile(QObject* parent = 0);
    void Initial(QString StringURL, QString FileName);

private slots:
    void startRequest(QUrl URL);
    void httpFinished();
    void httpReadyRead();

private:
    QUrl URL;
    QNetworkAccessManager qnam;
    QNetworkReply* Reply;
    QFile* File;
    int httpGetId;
    bool httpRequestAborted;
};

class QConfigFile: public QObject
{
    Q_OBJECT

public:
    QConfigFile(QObject* parent = 0);
    QString Read(const QString FileName, const QString Section, const QString Value,
              const QString Default);
    void Save(const QString FileName, const QString Section, const QString Value, const QString InValue);

private:
    QString Result;
    QString IniFile;
};

#endif

Файл пустой.

34

Помогите, пожалуйста.
(это своеобразный "UP").

35 (14.01.2011 20:59:24 отредактировано voral)

Все просто.
1. Ошибка

if ( QFile::exists(FileName) )
{
      File->remove();
}

меняем на

if ( QFile::exists(FileName) )
{
      File->remove(FileName);
}

2. Ошибка и главная

Сколько живет ваш объект? bx А ни сколько доли секунды. Соответственно ни чего не успевает принять. Достаточно в конце main.cpp  сделать так

....
    QDialog dlg;
    dlg.exec();
    return 0;
}

И вы получите свою картнку (Только окно не закрывайте моментально после открытия в данном примере это лишь костыль для создания задержки)

То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me".
GNU/Linux Debian

36

Т.е. вам нужно дать время программе скачать нужный файл. Как это сделать зависит от вашего проекта и задачи.

То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me".
GNU/Linux Debian

37

voral
А без этого костыля можно как-нибудь?

38

Darth Revan пишет:

voral
А без этого костыля можно как-нибудь?

Вместо

return 0;

Сделайте

return app.exec();

Где app - экземпляр QApplication.

39 (15.01.2011 19:12:43 отредактировано Peter)

А ещё установите qt4-doc-html, там есть /usr/share/qt4/doc/html/index.html,
в нём Tutorials and Examples, в Examples есть Network, в Network есть Download,
это именно то, что вы пытаетесь сделать. Там в main тоже

return  app.exec();

это стандартный спсоб запуска Qt-программ.

Конечно, можно заканчивать програму изнутри и сразу после окончания
скачивания файла вызовом

this->close();

кажется, так, сам давно уже в Qt ничего не делал.

Пётр.

Пётр.

40

Peter пишет:

это именно то, что вы пытаетесь сделать. Там в main тоже

return  app.exec();

это стандартный спсоб запуска Qt-программ.

Это способ запуска цикла обработки сообщений, который будет выполнятся до вызова функций quit() или exit(). Не надо никаких форм, просто в классе который скачивает файл надо создать сигнал downloadFinished() и сделать приблизительно следующее:

QApplication app(argc, argv);
MyOwnDownloader downloader;

downloader.connect(&downloader, SIGNAL(downloadFinished()), &app, SLOT(quit()));

/* тут начинаем качать файл */

return app.exec();

Как-то так.

41

Совершенно верно, я уже плохо помню терминологию.
Но там уже есть startRequest, httpFinished, м.б., в него и вставить команду выхода?

Пётр.

Пётр.

42

Peter пишет:

Совершенно верно, я уже плохо помню терминологию.
Но там уже есть startRequest, httpFinished, м.б., в него и вставить команду выхода?

Пётр.

По скольку, как я понял, пишеться самодостаточный класс. То лучше будет добавить сигнал. Котрый будет издаваться по звершению закачки файла. И соеденить этот сигнал со слотом для выхода.

То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me".
GNU/Linux Debian

43

voral пишет:
Peter пишет:

Совершенно верно, я уже плохо помню терминологию.
Но там уже есть startRequest, httpFinished, м.б., в него и вставить команду выхода?

Пётр.

По скольку, как я понял, пишеться самодостаточный класс. То лучше будет добавить сигнал. Котрый будет издаваться по звершению закачки файла. И соеденить этот сигнал со слотом для выхода.

Согласен, это будет правильнее, но нужно ли это вобще?
Ведь после окончания Download.Initial из него и так произойдёт выход, дальше
можно будет или выйти или что-то делать с файлом.

Пётр.

Пётр.

44

Peter пишет:

Ведь после окончания Download.Initial из него и так произойдёт выход, дальше
можно будет или выйти или что-то делать с файлом.

Только на момент выхода из Inital файл еще не скачан

То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me".
GNU/Linux Debian

45

Вообще, не в обиду этому форуму, есть отличный Russian Qt Forum  smile

Acer Extensa 5630G, openSuse 11.3

46 (21.01.2011 12:03:04 отредактировано voral)

На днях была необходимость написать нечто подобное. Т.е. нужно было дождаться скачивания и только потом грохаться. Сделал следующим образом.
во первых было добавлено в сам класс следующее:

...
private:
    void stopTimer(); //остановка таймера
    int timerId;  // Это id таймера. Таймер используем для реализации timeouta чтоб у нас навечно объект не повис
    bool fCanExit; //Это флаг возможности выхода. В конструкторе приравниваем к  true
    QEventLoop loop; //для реализации цикла обработки событий
protected:
    void timerEvent(QTimerEvent *event); //переопределяем процедуру обработки события таймера

После отправки запроса get или post

....
    this->timerId = this->startTimer(10000); //Запускаем таймер который будет обереать нас от бесконечного ожидания ответа
    if (!this->loop.isRunning()) this->loop.exec(); //если наш цикл обработки еще не запущен то запускаем
                                                                          //возможно в этом вам нет необходимости. у меня есть возможность (некоторая специфика)
                                                                          // повторного захода в этот запрос. 
...

Обработка события таймера

void VWebApi::timerEvent(QTimerEvent */* event */)
{
    this->stopTimer(); //останавливаем таймер. т.к. таймаут истек и нам уже он не нужен
    this->loop.exit(); //останавливем процесс обработки сообщений. Как только это произойдет мы выйдем 
                                // из метода отправляющего запрос (у вас Initial) и перейдем к следующей строке кода. Т.е. в вашем случае
                               // return 0 (main.cpp);
}

Процедура остановки таймера. Возможно это тоже можно вам не использовать. Это моя специфика: если отправляется повторный запрос мне надо перезапускать таймер

void VWebApi::stopTimer()
{
    this->killTimer(this->timerId);
    this->timerId=0;
}

Обработка сигнала окончания приема

void VWebApi::replyFinished(QNetworkReply* reply, replyType rplType)
{
...
   this->stopTimer(); // останавливаем таймер, чтобы у нас не грохнулся объект во время обработки
   fCanExit = // тут решаем можно уже выходить или нет
   if (this->fCanExit) this->loop.exit(); если можно то останавливаем обработку событий...
...
}

VWebApi - это имя моего класса, соответственно меняйте на свое ab
Т.к. дернул со своего проекта с некоторой спецификой, так что может быть вам что то можно тут и "почистить"

То что не убивает нас, делает нас сильнее! © Ницше.
When life puts you in tough situations, don’t say "why me". Just say "try me".
GNU/Linux Debian