Results 1 to 2 of 2

Thread: Qt Download Files from QThread Based On Qt Example Doesn't work

  1. #1
    Join Date
    May 2009
    Posts
    83

    Default Qt Download Files from QThread Based On Qt Example Doesn't work

    Hi i build simple example striped all irrelevant code and only the problematic code remains in general i have application that execute thread and inside this thread worker , i placed download code that supposed to download more then 30 files , this based on the Download Example Qt gives , the problem is that the QNetworkAccessManager Slot never invokes .
    can you please tell me what im doing wrong here ?

    Qt Code:
    1. class MainWindowContainer : public QMainWindow
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. MainWindowContainer(QWidget *parent = 0);
    7.  
    8.  
    9. public slots:
    10. void InvokeDownloadThread();
    11.  
    12. private:
    13. QPushButton *pushButtonInvokeThread;
    14. PhotosDownloadWorker* pm_hotosDownloadWorker;
    15. };
    16.  
    17. #include <QtGui>
    18. #include "MainWindowContainer.h"
    19.  
    20. MainWindowContainer::MainWindowContainer(QWidget* parent) :
    21. QMainWindow(parent)
    22. {
    23. pushButtonInvokeThread = new QPushButton(this);
    24. QHBoxLayout *layout = new QHBoxLayout;
    25. layout->addWidget(pushButtonInvokeThread);
    26. setLayout(layout);
    27. QObject::connect(pushButtonInvokeThread,SIGNAL(clicked()),this, SLOT(InvokeDownloadThread()));
    28.  
    29. }
    30. void MainWindowContainer::InvokeDownloadThread()
    31. {
    32. pm_hotosDownloadWorker = new PhotosDownloadWorker(this);
    33. pm_hotosDownloadWorker->Execute();
    34. }
    35.  
    36. class PhotosDownloadWorker : public QThread
    37. {
    38. Q_OBJECT
    39.  
    40. public :
    41. PhotosDownloadWorker(QObject *parent);
    42. ~PhotosDownloadWorker();
    43. void Execute();
    44. void append(const QStringList &urlList);
    45. bool saveToDisk(const QString &filename, QIODevice *data);
    46. QString saveFileName(const QUrl &url);
    47.  
    48. protected:
    49. void run();
    50.  
    51. private:
    52. bool m_abort;
    53. QList<QNetworkReply *> currentDownloads;
    54. QFile output;
    55. QNetworkAccessManager* networkMgr ;
    56.  
    57. public slots:
    58. void downloadFinished(QNetworkReply *reply);
    59. void startNextDownload(const QUrl &url);
    60.  
    61.  
    62.  
    63. };
    64.  
    65. #include "PhotosDownloadWorker.h"
    66. PhotosDownloadWorker::PhotosDownloadWorker(QObject *parent)
    67. : QThread(parent)
    68. {
    69. m_abort = false;
    70. networkMgr = new QNetworkAccessManager(this);
    71. connect(networkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*)));
    72. }
    73.  
    74. PhotosDownloadWorker::~PhotosDownloadWorker()
    75. {
    76. m_abort = true;
    77. wait();
    78. }
    79.  
    80. void PhotosDownloadWorker::Execute()
    81. {
    82. m_abort = false;
    83. start();
    84. }
    85. void PhotosDownloadWorker::run()
    86. {
    87. QStringList m_urlList;
    88.  
    89. m_urlList.append("http://....xxxx......jpg");
    90. m_urlList.append("http://....xxxx......jpg");
    91. m_urlList.append("http://....xxxx......jpg");
    92. m_urlList.append("http://....xxxx......jpg");
    93. m_urlList.append("http://....xxxx......jpg");
    94. m_urlList.append("http://....xxxx......jpg");
    95. m_urlList.append("http://....xxxx......jpg");
    96. m_urlList.append("http://....xxxx......jpg");
    97. m_urlList.append("http://....xxxx......jpg");
    98. m_urlList.append("http://....xxxx......jpg");
    99. m_urlList.append("http://....xxxx......jpg");
    100. m_urlList.append("http://....xxxx......jpg");
    101. m_urlList.append("http://....xxxx......jpg");
    102.  
    103. // x 30
    104. append(m_urlList);
    105. }
    106.  
    107.  
    108. void PhotosDownloadWorker::append(const QStringList &urlList)
    109. {
    110. foreach (QString url, urlList)
    111. {
    112. startNextDownload(QUrl::fromEncoded(url.toLocal8Bit()));
    113. }
    114. }
    115.  
    116.  
    117.  
    118.  
    119. void PhotosDownloadWorker::startNextDownload(const QUrl &url)
    120. {
    121. QNetworkRequest request(url);
    122. QNetworkReply *reply = networkMgr->get(request);
    123. currentDownloads.append(reply);
    124. }
    125. bool PhotosDownloadWorker::saveToDisk(const QString &filename, QIODevice *data)
    126. {
    127. QFile file(filename);
    128. if (!file.open(QIODevice::WriteOnly)) {
    129. fprintf(stderr, "Could not open %s for writing: %s\n",
    130. qPrintable(filename),
    131. qPrintable(file.errorString()));
    132. return false;
    133. }
    134.  
    135. file.write(data->readAll());
    136. file.close();
    137.  
    138. return true;
    139. }
    140.  
    141. void PhotosDownloadWorker::downloadFinished(QNetworkReply *reply)
    142. {
    143. QUrl url = reply->url();
    144. if (reply->error()) {
    145. fprintf(stderr, "Download of %s failed: %s\n",
    146. url.toEncoded().constData(),
    147. qPrintable(reply->errorString()));
    148. } else {
    149. QString filename = saveFileName(url);
    150. if (saveToDisk(filename, reply))
    151. printf("Download of %s succeeded (saved to %s)\n",
    152. url.toEncoded().constData(), qPrintable(filename));
    153. }
    154.  
    155. reply->deleteLater();
    156. currentDownloads.removeAll(reply);
    157. if (currentDownloads.isEmpty())
    158. {
    159.  
    160. this->exit();
    161. }
    162.  
    163. }
    164. QString PhotosDownloadWorker::saveFileName(const QUrl &url)
    165. {
    166. QString path = url.path();
    167. QString basename = QFileInfo(path).fileName();
    168.  
    169. if (basename.isEmpty())
    170. basename = "download";
    171.  
    172. if (QFile::exists(basename)) {
    173. // already exists, don't overwrite
    174. int i = 0;
    175. basename += '.';
    176. while (QFile::exists(basename + QString::number(i)))
    177. ++i;
    178.  
    179. basename += QString::number(i);
    180. }
    181.  
    182. return basename;
    183. }
    184.  
    185. //main
    186.  
    187. #include "MainWindowContainer.h"
    188.  
    189. int main(int argc, char *argv[])
    190. {
    191.  
    192. QApplication app(argc, argv);
    193. MainWindowContainer mainWindowContainer;
    194. mainWindowContainer.show();
    195. return app.exec();
    196. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Qt Download Files from QThread Based On Qt Example Doesn't work

    With out doweling too much on your code, the first thing which is wrong is that you are allocating you QNetworkAccessManager in the thread's constructor, which means its thread affinity is the main thread and NOT your thread, at the same time your QNetworkRequest which you pass to your 'networkMgr' is in your new thread.
    So with out looking much at the functionality you have a salad of mixed thread affinities.
    Be sure to read QThread docs and how thread affinity is determined.
    Fix your code acourdingly, and see if the problem is solved.
    Post again, with the corrected code if you still have a probelm.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

Similar Threads

  1. Replies: 1
    Last Post: 8th April 2011, 14:45
  2. Replies: 2
    Last Post: 4th September 2010, 07:18
  3. Replies: 0
    Last Post: 21st June 2010, 11:59
  4. QThread based Sniffer
    By hbtdtg in forum Qt Programming
    Replies: 1
    Last Post: 2nd August 2009, 13:23
  5. Pack all .qm files into .qrc, why doesn't work???
    By yxmaomao in forum Qt Programming
    Replies: 3
    Last Post: 8th May 2008, 20:38

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.