2012-11-03 1 views
2

현재 Qt 스레드에서 문제가 발생합니다.Qt QThread의 신호와 슬롯

QThread에서 파일 목록을 업로드해야하지만 분명히 업로드가 작동하지 않으며 슬롯이 호출되지 않습니다. 스레드의 메서드를 넣으면 완벽하게 작동합니다.

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::run() 
{ 
    for (int i = 0; i < Window::_listUpload.size(); i++) { 
     qDebug() << Window::_listUpload[i].getPath(); 
     this->sendFile(Window::_listUpload[i].getPath()); 
    } 
} 

가 sendfile을() 방법 : 여기

는 run() 메소드입니다

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

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

당신이 볼 수행 내 코드에 문제가 있습니까? 감사합니다.

답변

2

좋아, 알겠습니다.

업로드 할 때마다 exec()를 사용하여 QEventLoop을 시작해야하며, 업로드가 끝나면 QEventLoop을 끝내기 위해 exit()를 사용해야합니다. 그것은 이제 매력처럼 작동합니다.

1

sendFile() 메서드에서 QObject::connect()을 호출하는 것으로 보입니다.

QObject::connect()은 신호를 슬롯 방법으로 연결합니다. 신호는 emit signalName()과 같은 것을 사용하여 트리거 될 수 있습니다.

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

신호를 구현하지 마십시오는, 그들은 자동으로 Qt를 구현하고 있습니다 :처럼 예에서

, 당신의 UploadThread 헤더가 보일 것입니다.

에 sendfile()에서

, 그냥 전화 :

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

를 메인 스레드 (= GUI 스레드)에서 당신이 다음이 클래스 신호를 처리 슬롯 (현재 uploadFinished()와 recieveUploadProgress이 있어야합니다 () 메소드). GUI를 업데이트하려면 GUI 스레드에서 실행하는 것이 중요합니다.

마지막으로 연결해야합니다 (연결하는 것이 전화하는 것이 아닙니다). 업로드를 시작하십시오.

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

uploadThread.start() 

그들을 사용하는 방법에 대한 자세한 내용에 Qt의 Signal & Slot 문서에서보세요.

+0

uploadProgress() 및 finished() 신호를 다시 구현할 필요가 없습니다.이 신호는 QNetworkReply 및 QNetworkAccessManager에서 각각 구현됩니다. 나는 그들을 수동으로 방출 할 필요가 없다. 그래서, 내 코드가 작동하지, 안돼? –

+0

안녕하세요, 맞습니다. 나는 당신의 코드를 잘못 해석했다 ... – mreithub