Can Qt make a Synchronous network download without Qeventloop?



  • good evening guys.
    with QEventLoop, the code look like these:
    @
    class UrlDownloader : public QObject
    {
    Q_OBJECT
    public:
    UrlDownloader(QUrl url, QObject parent = 0)
    : QObject(parent)
    {
    connect(&m_WebCtrl, SIGNAL(finished(QNetworkReply
    )), this, SLOT(fileDownloaded(QNetworkReply*)));
    QNetworkRequest request(url);
    m_WebCtrl.get(request);
    }
    signals:
    void downloadEnd();

    private slots:
    void fileDownloaded(QNetworkReply* pReply)
    {
    m_DownloadedData = pReply->readAll();
    QFile downLoadFile("D:/test.doc");
    downLoadFile.open(QIODevice::ReadWrite);
    downLoadFile.write(m_DownloadedData);
    downLoadFile.close();

        pReply->deleteLater();
        emit downloadEnd();
    }
    

    private:
    QNetworkAccessManager m_WebCtrl;
    QByteArray m_DownloadedData;
    };

    void foo()
    {
    QEventLoop loop;
    UrlDownloader d(QUrl("http://qt-project.org"));
    connect(&d, SIGNAL(downloadEnd()), &loop, SLOT(quit()));
    loop.exec();
    ...
    }

    but those code would entry the eventloop , I want to avoid this usage, Can Qt has a way to download url file Synchronous without QEventLoop?

    thanks.

    @



  • wow, It is better if a timeout could be set in here...


  • Moderators

    AFAIK thats not possible.
    What is wrong with the usage of the QEventLoop like you already do?



  • for that I want to block all event until the download is finished.I has try to create QNetworkRequest's work in QThread's run function, but it seem doesn't work.
    [quote author="raven-worx" date="1377785758"]AFAIK thats not possible.
    What is wrong with the usage of the QEventLoop like you already do?[/quote]



  • if you want to block until a signal is received you could use "this approach":http://developer.nokia.com/Community/Wiki/How_to_wait_synchronously_for_a_Signal_in_Qt, but be aware that this has pitfalls and is not really recommended.

    For a discussion about the use of this method see "this thread":http://qt-project.org/forums/viewthread/24109/ .



  • Is it really the events you want to kill, or only the possibility of the user pressing buttons etc?
    To to that you might want to create a simple qdialog derived class as modal and show a "download" progressBar. Grey out the ok button until done or timeout and overwrite the closeEvent (x on the window) when not done yet. That way the user is unable to press any button on other widgets.
    Everything in modern OS runs on event and not previous on time! So killing the event loop is very highly discouraged!!! Also the user might think the program has crashed because the GUI is "dead"



  • I has ever try this method, this code would make the programe into the evenloop which i don't wanted it be . I just want it be fully blocked until download finished or timeout.
    Not I try to use QThread to exec a download , the code is look like these:

    @
    class UrlCacheFileDownloader : public QThread
    {
    Q_OBJECT
    public:
    UrlCacheFileDownloader(QUrl url, QSharedPointer<QWaitCondition> waitCondition, QObject parent = 0)
    : QThread(parent)
    {
    m_url = url;
    m_spWaitCondition = waitCondition;
    }
    protected:
    void run(){
    QNetworkRequest request(m_url);
    QNetworkAccessManager mgr;
    connect(&mgr, SIGNAL(finished(QNetworkReply
    )), this, SLOT(fileDownloaded(QNetworkReply*)), Qt::DirectConnection);
    mgr.get(request);
    exec();
    };
    .............
    private slots:
    void fileDownloaded(QNetworkReply* pReply)
    {
    m_DownloadedData = pReply->readAll();
    pReply->deleteLater();
    buildCacheFile();
    m_spWaitCondition->wakeAll();
    }
    private:
    .....
    };

    void download()
    {
    QMutex mutex;
    mutex.lock();
    QSharedPointer<QWaitCondition> spWaitCondition(new QWaitCondition());
    UrlCacheFileDownloader d(QUrl("http://qt-project.org/"), spWaitCondition);
    d.start();
    spWaitCondition->wait(&mutex, 5000);
    filename = d.downloadFileName();
    mutex.unlock();
    qDebug()<<"file:"<< filename;
    }
    @

    but these code just work once, program crash at the second time.What's wrong with it ?

    [quote author="KA51O" date="1377844353"]if you want to block until a signal is received you could use "this approach":http://developer.nokia.com/Community/Wiki/How_to_wait_synchronously_for_a_Signal_in_Qt, but be aware that this has pitfalls and is not really recommended.

    For a discussion about the use of this method see "this thread":http://qt-project.org/forums/viewthread/24109/ .[/quote]


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.