в ожидании сигнала - PullRequest
       21

в ожидании сигнала

11 голосов
/ 16 июня 2010

Я работаю над приложением, которое загружает содержимое файла на сервер.

Для загрузки файла на сервер я использую класс 'QNetworkAccessManager'.Поскольку он работает асинхронно, я изменил его на синхронный, используя 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();
      }
}

В моем примере приложения у меня есть 2 окна.1-й, чтобы выбрать файлы, 2-й, чтобы показать прогресс.

Когда пользователь нажимает кнопку загрузки в первом окне, отображается 2-е окно, а затем я создаю объект FileTransfer и запускаюзагрузка.

При загрузке файла, если пользователь закрывает форму, в деструкторе окна я вызываю остановку ' FileTransfer ', после чего удаляю ' FileTransfer 'object.

Но здесь функция Upload () еще не завершена, поэтому она вылетит.

Пожалуйста, помогите мне: Как ждать в функции stop () , пока не будет завершена функция Upload ()

Ответы [ 3 ]

19 голосов
/ 16 июня 2010

Из того, что я вижу из вашего кода, вы выполняете QEventLoop, но на самом деле вы не подключаете его слот "выход" к какому-либо сигналу.Возьмите в качестве примера ниже: логин - это QHttp - а код взят из чего-то другого - но принцип применим.

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

Это может быть применено к вашему коду, если я не ошибаюсьвот так ...

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

Извините, если я ошибся в вашем запросе!После перерыва я только начинаю разбираться с qt, но я верю, что вы это имеете в виду!Удачи!

0 голосов
/ 28 июня 2013

Лично я бы рекомендовал не использовать ни один из этих ответов. Было бы достаточно подключить защелку обратного отсчета к сигналу.

Чтобы вы могли написать:

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

latch.wait();

Для этого вам понадобится обертка:

class Latch : public QObject {
    Q_OBJECT
public:
    Latch( uint count );
    void wait();
public slots:
    void countDown();
private:
    gcl::countdown_latch _latch;
};
0 голосов
/ 16 июня 2010

Я думаю, вам нужно добавить что-то подобное в функцию загрузки:

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

Полный текстовый код: datacod-qt-tools

Надеюсь, это поможет.

...