2011-04-13 58 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