2

現在、Qtスレッドで問題が発生しています。

QThreadにファイルのリストをアップロードする必要がありますが、1つのアップロードが機能しないか、スロットが呼び出されないようです。メソッドをスレッドから外すと、完全に機能します。

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;
}

私のコードに問題がありますか?ありがとうございました。

4

2 に答える 2

2

わかったよ。

アップロードごとに、exec()を使用してQEventLoopを開始する必要があり、アップロードの最後に、QEventLoopを終了するためにexit()を使用する必要があります。今では魅力のように機能します。

于 2012-11-04T01:19:41.470 に答える
1

メソッドを呼び出しているようQObject::connect()ですsendFile()

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のSignal&Slotのドキュメントを参照してください。

于 2012-11-03T19:07:25.977 に答える