Reputation: 1812
This is for pure testing purpose and for my curiosity. I use my DataDownloader class to get a list of data from server. It works with different urls, like http://tiny-file-url, http://big-file-url. But if I pass in two identical urls, http://tiny-file-url, http://tiny-file-url, and the data from http://tiny-file-url is quite small, then the second reply from QNetworkAccessManager is empty. However two http://big-file-url seem to work. I'm wondering if QNetworkAccessManager does some magic when request small data from the same url? I can't seem to get any relevant information on Qt document site.
Here is my DataDownloader
class:
class DataDownloader : public QObject
{
Q_OBJECT
public:
explicit DataDownloader(QObject* parent = 0);
virtual ~DataDownloader();
QByteArray data() const;
void cancel();
void download(QUrl url);
signals:
void isComplete();
private slots:
void complete(QNetworkReply* reply);
private:
QNetworkAccessManager m_NetworkManager;
QByteArray m_Data;
QNetworkReply* m_pReply;
};
DataDownloader::DataDownloader(QUrl url, QObject* parent) :QObject(parent)
{
connect(&m_NetworkManager, SIGNAL(finished(QNetworkReply*)),
SLOT(complete(QNetworkReply*)));
}
DataDownloader::~DataDownloader()
{
}
void DataDownloader::complete(QNetworkReply* reply)
{
// in the first download it returns data
// but the second time m_Data is empty
m_Data = reply->readAll();
reply->deleteLater();
if (!m_Data.isEmpty()) {
// no signal on the second try
emit isComplete();
}
}
QByteArray DataDownloader::data() const
{
return m_Data;
}
void DataDownloader::cancel()
{
m_pReply->abort();
}
void DataDownloader::download(QUrl url)
{
QNetworkRequest request(url);
m_pReply = m_NetworkManager.get(request);
}
The code that invokes this DataDownloader
is as below:
void PluginManager::downloadPlugins()
{
m_DownloadIndex++;
savePlugin();
if (m_DownloadIndex < m_PluginList.size()) {
QUrl url;
// alway return the same url here
QString pluginUrl = getPluginUrl(m_PluginList.at(m_DownloadIndex));
url.setUrl(pluginUrl);
if (m_pPluginDownloader == NULL) {
m_pPluginDownloader = new DataDownloader();
// call this function again when isComplete is signaled
connect(m_pPluginDownloader, SIGNAL(isComplete()), this, SLOT(downloadPlugins()));
}
m_pPluginDownloader->download(url);
}
}
Upvotes: 2
Views: 1480
Reputation: 32635
I think here isComplete
is emitted before you connect it to downloadPlugins
slot. Try to first connect this signal and then do the download action :
m_pPluginDownloader = new DataDownloader(url);
connect(m_pPluginDownloader, SIGNAL(isComplete()), this, SLOT(downloadPlugins()));
m_pPluginDownloader.download();
Instead of performing get action in the constructor, do it in a slot called download
:
void DataDownloader::download()
{
QNetworkRequest request(url);
m_pReply = m_NetworkManager.get(request);
}
Another point is that it's not necessary to make a new instance of DataDownloader
every time. You can create an instance in the constructor of PluginManager
and connect isComplete
signal once there. You can then provide the url as argument in download
slot.
Upvotes: 1