В ожидании сигнала
Я работаю над приложением, которое загружает содержимое файла на сервер.
Для загрузки файла на сервер я использую класс "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-й, чтобы показать прогресс.
Когда пользователь нажимает кнопку загрузки в первом окне, отображается второе окно, а затем я создаю объект FileTransfer и начинаю загрузку.
При загрузке файла, если пользователь закрывает форму, в деструкторе окна я вызываю остановкуFileTransfer, после чего удаляю объектFileTransfer.
Но здесь функция Upload() еще не завершена, поэтому она вылетит.
Пожалуйста, помогите мне: Как ждать в функции 'stop ()', пока функция Upload() не будет завершена
3 ответа
Из того, что я вижу из вашего кода, вы выполняете 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, но я верю, что вы это имеете в виду! Удачи!
Лично я бы рекомендовал не использовать ни один из этих ответов. Было бы достаточно подключить защелку обратного отсчета к сигналу.
Чтобы вы могли написать:
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;
};
Я думаю, вам нужно добавить что-то подобное в функцию загрузки:
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
Надеюсь, это поможет.