2012-11-03 113 views
2

我目前在Qt線程上遇到問題。Qt Qt中的信號和插槽

我必須上傳一個QThread中的文件列表,但顯然一個上傳不起作用和/或我的插槽永遠不會被調用。如果我把這些方法從線程中解放出來,那麼它就可以完美運行

這裏是run()方法:

void UploadThread::run() 
{ 
    for (int i = 0; i < Window::_listUpload.size(); i++) { 
     qDebug() << Window::_listUpload[i].getPath(); 
     this->sendFile(Window::_listUpload[i].getPath()); 
    } 
} 

這裏是SENDFILE()方法:

void UploadThread::sendFile(const QString & path) 
{ 
    QFreeDesktopMime mime; 
    QNetworkAccessManager *manager = new QNetworkAccessManager; 
    QFileInfo fInfo(path); 
    QNetworkRequest request(QUrl("http://my-url/")); 
    QNetworkReply *reply; 

    QString bound = "---------------------------723690991551375881941828858"; 
    QByteArray data(QString("--"+bound+"\r\n").toAscii()); 
    data += "Content-Disposition: form-data; name=\"action\"\r\n\r\n"; 
    data += "\r\n"; 
    data += QString("--" + bound + "\r\n").toAscii(); 
    data += "Content-Disposition: form-data; name=\"file\"; filename=\""+fInfo.fileName()+"\"\r\n"; 
    data += "Content-Type: "+mime.fromFile(path)+"\r\n\r\n"; 

    QFile file(fInfo.absoluteFilePath()); 
    file.open(QIODevice::ReadOnly); 
    data += file.readAll(); 
    data += "\r\n"; 
    data += QString("--" + bound + "\r\n").toAscii(); 
    data += QString("--" + bound + "\r\n").toAscii(); 
    data += "Content-Disposition: form-data; name=\"desc\"\r\n\r\n"; 
    data += "Description for my image here :)\r\n"; 
    data += "\r\n"; 
    request.setRawHeader(QString("Accept-Encoding").toAscii(), QString("gzip,deflate").toAscii()); 
    request.setRawHeader(QString("Content-Type").toAscii(),QString("multipart/form-data; boundary=" + bound).toAscii()); 
    request.setRawHeader(QString("Content-Length").toAscii(), QString::number(data.length()).toAscii()); 

    reply = manager->post(request, data); 

    QObject::connect(reply, SIGNAL(uploadProgress(qint64,qint64)), currentThread(), SLOT(receiveUploadProgress(qint64, qint64))); 
    QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), currentThread(), SLOT(uploadFinished(QNetworkReply*))); 
} 

這裏是我的槽:

void UploadThread::uploadFinished(QNetworkReply *reply) 
{ 
    _isFinished = true; 
} 

void UploadThread::receiveUploadProgress(qint64 bytesSent, qint64 bytesTotal) 
{ 
    qDebug() << bytesSent << " " << bytesTotal; 
} 

你看我的代碼中存在問題? 謝謝。

回答

2

好的,我明白了。

對於每次上傳,我需要使用exec()啓動QEventLoop,並且在上傳結束時,我必須使用exit()來完成QEventLoop。它現在像一個魅力。

1

您好像在您的sendFile()方法中調用QObject::connect()

QObject::connect()用插槽方法連接信號。信號可以使用類似emit signalName()的東西來觸發。

在你的榜樣,你的UploadThread頭應該是這樣的:

class UploadThread: public QThread { 
    ... 
signals: 
    void uploadProgress(int sent, int total); 
    void uploadFinished(QNetworkReply *reply); 
} 

不執行信號,它們會自動被Qt實現。

在SENDFILE(),只是稱他們爲:

... 
emit uploadProgress(sent, total); 
... 

在你的主線程(= GUI線程),那麼你應該有一個具有一類插槽處理信號(當前的uploadFinished()和recieveUploadProgress( ) 方法)。如果你想更新GUI,在GUI線程中執行它們是很重要的。

最後你必須連接它們(連接並不意味着打電話給他們)並開始上傳。

UploadThread *uploadThread = new UploadThread(); 
connect(uploadThread, SIGNAL(uploadProgress(...)), objectInGuiThread, SLOT(actualUploadProgressSlot(...))); 

uploadThread.start() 

查看Qt's Signal & Slot關於如何使用它們的更多信息。

+0

我不必重新實現uploadProgress()和finished()信號,它們分別由QNetworkReply和QNetworkAccessManager實現。我不必手動發射它們。所以,我的代碼應該工作,不是嗎? –

+0

嗨,你是對的。我錯誤地解釋了你的代碼,Sry ...... – mreithub