11

I am working on an application which uploads the content of the file to server.

To upload the file to server I am using ‘QNetworkAccessManager’ class. Since it works as asynchronous way, I changed it to work as synchronous way by using QEventLoop.

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 my sample application I have 2 windows. 1st to select the files and 2nd to show the progress.

When user click on upload button in the first window, the 2nd window will be displayed and then I create the FileTransfer object and start uploading.

While uploading the file if user closes the form then in the destructor of the window I call the stop of ‘FileTransfer’ after that I delete the ‘FileTransfer’ object.

But here the Upload() function is not yet completed so it will crash.

Please help me to: How to wait in 'stop()' function until the Upload() function is completed

starsplusplus
  • 1,232
  • 3
  • 19
  • 32
Umesha MS
  • 2,861
  • 8
  • 41
  • 60

3 Answers3

19

From what I can see from your code, you're executing a QEventLoop but you're not actually connecting its "quit" slot to any signal. Take the below as an example, login is a QHttp - and the code is taken from something different - but the principle applies.

/* 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();

This could be applied to your code, if I'm not mistaken, like this...

/* 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();

Apologies if I've mistaken your query! I'm only getting to grips with qt again after a break, but I believe this is what you mean! Good luck!

EnOpenUK
  • 391
  • 1
  • 5
  • yes, i added the code to exit the event loop as soon as we get finish slot. but the problem is while downloading the file if user stops the connection and delete the object. but the upload function is not yet completed. at this time it will crash. – Umesha MS Jun 16 '10 at 11:09
0

Personally, I would recommend to not use any of these answers. It would be sufficient to connect a countdown latch to the signal.

So you could write:

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

latch.wait();

For this you would need a wrapper:

class Latch : public QObject {
    Q_OBJECT
public:
    Latch( uint count );
    void wait();
public slots:
    void countDown();
private:
    gcl::countdown_latch _latch;
};
abergmeier
  • 13,224
  • 13
  • 64
  • 120
  • I could be wrong, but I don't think that will work because the gcl countdown latch is meant for blocking a thread. The put() call happens in the main GUI thread, then QNetworkAccessManager fetches the webpage in a separate thread, and the finished() slot gets executed in the main GUI thread. So using this code with the example would just cause the entire app to lock up. It would be possible move the finished slot into a different thread, but that would require a lot more code which isn't shown here. – Ph0t0n Mar 04 '18 at 01:20
0

I think you need to add something like that in your upload function:

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

Here is the full text code: datacod-qt-tools

Hope it help.

mosg
  • 12,041
  • 12
  • 65
  • 87