2010-06-16 24 views
11

Ich arbeite an einer Anwendung, die den Inhalt der Datei auf den Server hochlädt.Warten auf ein Signal

Zum Hochladen der Datei zum Server verwende ich die Klasse 'QNetworkAccessManager'. Da es asynchron arbeitet, habe ich es so geändert, dass es mit QEventLoop synchron arbeitet.

Class FileTransfer 
{ 
Public : 
    QNetworkAccessManager mNetworkManager; 
    Void Upload(QNetworkRequest request, QIODevice *data) 
    { 
      responce = mNetworkManager.put(request, data); 
      EventLoop.exec(); 
      ReadResponce(responce); 
     } 

     Void Stop() 
     { 
      responce ->close(); 
     } 
} 

In meiner Beispielanwendung habe ich 2 Fenster. 1. um die Dateien auszuwählen und 2. um den Fortschritt anzuzeigen.

Wenn der Benutzer im ersten Fenster auf den Upload-Button klickt, wird das zweite Fenster angezeigt und dann erstelle ich das FileTransfer Objekt und beginne mit dem Hochladen.

beim Hochladen der Datei, wenn der Benutzer das Formular dann im Destruktor des Fensters schließt ich den Anschlag von ‚Filetransfer‘ nennen nach, dass ich das Objekt ‚Filetransfer‘ löschen.

Aber hier ist die Upload() Funktion ist noch nicht abgeschlossen, so wird es zum Absturz bringen.

Bitte helfen Sie mir zu: Wie in ‚stop()‘ Funktion bis zum Hochladen warten() Funktion

abgeschlossen ist

Antwort

19

Von dem, was ich aus Ihrem Code ersehen kann, führen Sie einen QEventLoop aus, aber Sie verbinden seinen "quit" -Slot nicht mit irgendeinem Signal. Nehmen Sie das unten als Beispiel, login ist ein QHttp - und der Code wird von etwas anderem genommen - aber das Prinzip trifft zu.

/* Create the QEventLoop */ 
QEventLoop pause; 
/* connect the QHttp.requestFinished() Signal to the QEventLoop.quit() Slot */ 
connect(&login, SIGNAL(requestFinished(int, bool)), &pause, SLOT(quit())); 
/* The code that will run during the QEventLoop */ 
login.request(header,&logmein,&result); 
/* Execute the QEventLoop - it will quit when the above finished due to the connect() */ 
pause.exec(); 

Dies könnte zu Ihrem Code angewendet werden, wenn ich mich nicht irre, so ...

/* connect the signal to the relevant slot */ 
connect(&mNetworkManager, SIGNAL(finished(QNetworkReply)), &EventLoop, SLOT(quit())); 
/* Execute the code that will run during QEventLoop */ 
responce = mNetworkManager.put(request, data); 
/* Execute the QEventLoop */ 
EventLoop.exec(); 

Entschuldigt, wenn ich Ihre Frage falsch habe! Ich komme erst nach einer Pause wieder mit qt zurecht, aber ich glaube, das ist es, was du meinst! Viel Glück!

+0

ja, habe ich den Code, sobald die Ereignisschleife zu verlassen, wie wir Finish Slot erhalten:

Latch latch(1); QObject::connect(reply, SIGNAL(finished()), &latch, SLOT(countDown())); latch.wait(); 

Dazu geben Sie einen Wrapper benötigen würde. Das Problem liegt jedoch beim Herunterladen der Datei, wenn der Benutzer die Verbindung beendet und das Objekt löscht. aber die Upload-Funktion ist noch nicht abgeschlossen. Zu dieser Zeit wird es zusammenbrechen. –

0

Ich glaube, Sie brauchen so etwas wie die in Ihrer Upload-Funktion hinzuzufügen:

if (upf->openFile()) 
{ 
    reply = manager->post(request, upf); 
    connect(reply, SIGNAL(uploadProgress(qint64,qint64)), this, SIGNAL(progress(qint64,qint64))); 
    connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); 
    isInProgress = true; 
    emit started(); 
} else 
{ 
    emit finished(true, false, tr("Error: can't open file %1").arg(filename)); 
} 

Hier ist der vollständige Text Code: datacod-qt-tools

Hoffe, es hilft.

0

Persönlich würde ich empfehlen, keine dieser Antworten zu verwenden. Es wäre ausreichend, einen Countdown-Latch mit dem Signal zu verbinden.

So könnte man schreiben:

class Latch : public QObject { 
    Q_OBJECT 
public: 
    Latch(uint count); 
    void wait(); 
public slots: 
    void countDown(); 
private: 
    gcl::countdown_latch _latch; 
}; 
+0

Ich könnte mich irren, aber ich denke nicht, dass das funktioniert, weil der Countdown-Schalter gcl zum Blockieren eines Threads gedacht ist.Der put() - Aufruf erfolgt im Haupt-GUI-Thread, dann ruft QNetworkAccessManager die Webseite in einem separaten Thread ab und der fertige() Slot wird im Haupt-GUI-Thread ausgeführt. Wenn Sie diesen Code mit dem Beispiel verwenden, wird die gesamte App blockiert. Es wäre möglich, den fertigen Slot in einen anderen Thread zu verschieben, aber das würde viel mehr Code erfordern, der hier nicht gezeigt wird. – Ph0t0n