利用QNetworkAccessManager和QHttp完成文件下载问题
我的源码如下:
// 头文件#ifndef SYCHRONIZATION_TASK_H#define SYCHRONIZATION_TASK_H#include <QHttp>#include <QFile>#include <QNetworkAccessManager>#include <QUrl>#include <QNetworkReply>class SynchronizationTask : public QObject{ Q_OBJECTpublic: SynchronizationTask(); void run(); void startRequest(QUrl url);signals: void synchronizationFinish(); void synchronizationFail(const QString& msg);private slots: void httpFinished(); void httpReadyRead();private: QHttp *m_http; QString m_state; QUrl m_url; QNetworkAccessManager m_qnam; QNetworkReply *m_reply; QFile *m_file; int m_httpGetId;};#endif
// 源文件#include "sychronizationtask.h"#include <QMessageBox>#include <QFileInfo>#include <QNetworkRequest>SynchronizationTask::SynchronizationTask(HostWindow* host, const QString& state) : m_host(host), m_state(state){}void SynchronizationTask::run(){ try { m_url = tr("http://www.baidu.com"); QString fileName = QFileInfo(m_url.path()).fileName(); if (fileName.isEmpty()) fileName = "index.html"; if (QFile::exists(fileName)) { QFile::remove(fileName); } m_file = new QFile(fileName); if (!m_file->open(QIODevice::WriteOnly)) { delete m_file; m_file = 0; emit synchronizationFail(tr("Unable to save the file %1: %2.") .arg(fileName).arg(m_file->errorString())); } // schedule the request startRequest(m_url); } catch(const std::exception &e) { emit synchronizationFail(e.what()); } catch(...) { emit synchronizationFail(tr("Unknown exception")); }}void SynchronizationTask::startRequest(QUrl url){ try { QNetworkRequest request; request.setUrl(url); m_reply = m_qnam.get(request); connect(m_reply, SIGNAL(finished()), this, SLOT(httpFinished())); connect(m_reply, SIGNAL(readyRead()),this, SLOT(httpReadyRead())); } catch(const std::exception &e) { emit synchronizationFail(e.what()); } catch(...) { emit synchronizationFail(tr("Unknown exception")); }}void SynchronizationTask::httpFinished(){ try { m_file->flush(); m_file->close(); QVariant redirectionTarget = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute); if (m_reply->error()) { m_file->remove(); } else if (!redirectionTarget.isNull()) { QUrl newUrl = m_url.resolved(redirectionTarget.toUrl()); if (QMessageBox::question(m_host, tr("HTTP"), tr("Redirect to %1 ?").arg(newUrl.toString()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { m_url = newUrl; m_reply->deleteLater(); m_file->open(QIODevice::WriteOnly); m_file->resize(0); startRequest(m_url); return; } } m_reply->deleteLater(); m_reply = 0; delete m_file; m_file = 0; emit synchronizationFinish(); } catch(const std::exception &e) { emit synchronizationFail(e.what()); } catch(...) { emit synchronizationFail(tr("Unknown exception")); }}void SynchronizationTask::httpReadyRead(){ if (m_file) m_file->write(m_reply->readAll());}
程序执行到startRequest没有问题,之后一直没进入httpReadyRead和httpFinished函数。我不知道为什么?
这个我是按照qt例子中的写的。
[解决办法]
楼主的代码是在主线程里还是在次线程里?
顺便说一下,楼主写这么多try catch干嘛?Qt又不会抛异常
[解决办法]
startRequest里的代码除了阅读起来比较怪异,其它的倒也没什么问题。
所以我怀疑这段代码是在次线程里运行,但次线程没有进入事件循环造成的。
再顺便说一下,用QNetworkAccessManager就够了,怎么又扯上QHttp了呢?
[解决办法]
恩,放主线程里,QNetworkAccessManager本来就是多线程的,所以不需要再搞个线程了。而且你如果真在次线程中,也是不能弹QMessageBox的!
[解决办法]