2011-04-13 55 views
0

嗨,我建立簡單的例子條帶化所有不相關的代碼,只有有問題的代碼仍然 一般我有應用程序執行線程和內線程工人,我把下載代碼那應該下載超過30個文件,這是基於Qt下載示例給出的,問題是QNetworkAccessManager插槽從不調用。
你能告訴我在這裏做錯了什麼?Qt從QThread下載文件基於Qt示例不起作用

class MainWindowContainer : public QMainWindow 
{ 
    Q_OBJECT 

public: 
    MainWindowContainer(QWidget *parent = 0); 


public slots: 
    void InvokeDownloadThread(); 

private: 
    QPushButton *pushButtonInvokeThread; 
    PhotosDownloadWorker* pm_hotosDownloadWorker; 
    }; 

#include <QtGui> 
#include "MainWindowContainer.h" 

MainWindowContainer::MainWindowContainer(QWidget* parent) : 
            QMainWindow(parent) 
{ 
    pushButtonInvokeThread = new QPushButton(this); 
    QHBoxLayout *layout = new QHBoxLayout; 
    layout->addWidget(pushButtonInvokeThread); 
    setLayout(layout); 
    QObject::connect(pushButtonInvokeThread,SIGNAL(clicked()),this, SLOT(InvokeDownloadThread())); 

} 
void MainWindowContainer::InvokeDownloadThread() 
{ 
    pm_hotosDownloadWorker = new PhotosDownloadWorker(this); 
    pm_hotosDownloadWorker->Execute(); 
} 

class PhotosDownloadWorker : public QThread 
{ 
    Q_OBJECT 

public : 
    PhotosDownloadWorker(QObject *parent); 
    ~PhotosDownloadWorker(); 
    void Execute(); 
    void append(const QStringList &urlList); 
    bool saveToDisk(const QString &filename, QIODevice *data); 
    QString saveFileName(const QUrl &url); 

protected: 
    void run(); 

private: 
    bool m_abort; 
    QList<QNetworkReply *> currentDownloads; 
    QFile output; 
    QNetworkAccessManager* networkMgr ; 

    public slots: 
    void downloadFinished(QNetworkReply *reply); 
    void startNextDownload(const QUrl &url); 



}; 

#include "PhotosDownloadWorker.h" 
PhotosDownloadWorker::PhotosDownloadWorker(QObject *parent) 
    : QThread(parent) 
{ 
    m_abort = false; 
    networkMgr = new QNetworkAccessManager(this); 
    connect(networkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*))); 
} 

PhotosDownloadWorker::~PhotosDownloadWorker() 
{ 
    m_abort = true; 
    wait(); 
} 

void PhotosDownloadWorker::Execute() 
{ 
    m_abort = false; 
    start(); 
} 
void PhotosDownloadWorker::run() 
{ 
    QStringList m_urlList; 

    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg"); 

    // x 30 
    append(m_urlList); 
} 


void PhotosDownloadWorker::append(const QStringList &urlList) 
{ 
    foreach (QString url, urlList) 
    { 
     startNextDownload(QUrl::fromEncoded(url.toLocal8Bit())); 
    } 
} 

void PhotosDownloadWorker::startNextDownload(const QUrl &url) 
{ 
    QNetworkRequest request(url); 
    QNetworkReply *reply = networkMgr->get(request); 
    currentDownloads.append(reply); 
} 
bool PhotosDownloadWorker::saveToDisk(const QString &filename, QIODevice *data) 
{ 
    QFile file(filename); 
    if (!file.open(QIODevice::WriteOnly)) { 
     fprintf(stderr, "Could not open %s for writing: %s\n", 
       qPrintable(filename), 
       qPrintable(file.errorString())); 
     return false; 
    } 

    file.write(data->readAll()); 
    file.close(); 

    return true; 
} 

void PhotosDownloadWorker::downloadFinished(QNetworkReply *reply) 
{ 
    QUrl url = reply->url(); 
    if (reply->error()) { 
     fprintf(stderr, "Download of %s failed: %s\n", 
       url.toEncoded().constData(), 
       qPrintable(reply->errorString())); 
    } else { 
     QString filename = saveFileName(url); 
     if (saveToDisk(filename, reply)) 
      printf("Download of %s succeeded (saved to %s)\n", 
        url.toEncoded().constData(), qPrintable(filename)); 
    } 

    reply->deleteLater(); 
    currentDownloads.removeAll(reply); 
    if (currentDownloads.isEmpty()) 
    { 

     this->exit(); 
    } 

} 
QString PhotosDownloadWorker::saveFileName(const QUrl &url) 
{ 
    QString path = url.path(); 
    QString basename = QFileInfo(path).fileName(); 

    if (basename.isEmpty()) 
     basename = "download"; 

    if (QFile::exists(basename)) { 
     // already exists, don't overwrite 
     int i = 0; 
     basename += '.'; 
     while (QFile::exists(basename + QString::number(i))) 
      ++i; 

     basename += QString::number(i); 
    } 

    return basename; 
} 

//main 

#include "MainWindowContainer.h" 

int main(int argc, char *argv[]) 
{ 

    QApplication app(argc, argv); 
    MainWindowContainer mainWindowContainer; 
    mainWindowContainer.show(); 
    return app.exec(); 
} 
+0

您使用了哪些示例?你能指出我們的在線鏈接嗎? – 2011-04-13 09:25:51

回答

1

儘管您在代碼中調用了「networkMgr-> get(request)」,您的線程可能會在實際下載開始之前退出。嘗試將「exec()」調用放在「QThread :: run()」方法的最底部,以便在QNetworkAccessManager需要能夠工作的線程中輸入事件循環。此外,這將阻止線程過早完成執行。您的代碼如下所示:

void PhotosDownloadWorker::run() 
{ 
    QStringList m_urlList; 

    m_urlList.append("http://....xxxx......jpg"); 
    m_urlList.append("http://....xxxx......jpg");  
    // x 30 
    append(m_urlList); 

    exec(); 
} 
+0

是它的答案,謝謝你最後一個問題..我怎樣才能終止線程什麼是exec()調用後的最佳方式? – user63898 2011-04-13 19:31:04

+0

您可以使用QThread :: quit()或QThread :: exit()。通過最後一個,您可以傳遞一個結果代碼以從您的QThread :: exec()調用中返回。通常我使用QThread :: quit()。所以你甚至可以把你的最終下載完成()信號連接到QThread :: quit()插槽。 – Barbaris 2011-04-13 20:03:50

+0

你可以給我例子,我沒有明白 – user63898 2011-04-14 05:13:33

0

我認爲如果參數列表不匹配,它甚至不會將信號連接到插槽。有關運行時的警告(應用程序輸出選項卡),請參閱調試器輸出。

所以,與其

connect(networkMgr, SIGNAL(readyRead()), this, SLOT(downloadFinished(QNetworkReply*))); 

connect(networkMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadFinished(QNetworkReply*))); 

處理錯誤通過QNetworkReply的error signal完成。在您之後get您可以連接到信號。

+0

我把它取代它是我的錯誤,但它仍然不起作用 – user63898 2011-04-13 07:41:41

+0

我編輯了我的答案。請報告它是如何發生的。 – 2011-04-13 14:58:27