Сетевой ответ после завершения программы

Я написал программу, которая получает исходный код веб-страницы из URL-адреса, но у меня есть проблема, потому что этот код печатается на экране, когда программа заканчивается, и я не могу использовать данные, которые я скачал. Я думаю, что проблема в том, что программа ждет СИГНАЛА (завершено ()). Есть ли способ обработать загруженные данные в моей программе перед завершением?

void Get::getCode()
{
    networkManager = new QNetworkAccessManager(this);
    link = "http://example.com/";
    networkManager->get(QNetworkRequest(QUrl(link)));
    connect(networkManager, SIGNAL(finished(QNetworkReply*)), &process, SLOT(replyFinished(QNetworkReply*)));

    //QDesktopServices::openUrl(QUrl(link));
}

...

    void Process::replyFinished(QNetworkReply* pReply)
{
    QString source(pReply->readAll());
    printf("%s\n", source.toStdString().c_str());
}

...

int main(int argc, char *argv[]){

    QApplication a(argc, argv);

    Get get; get.getCode();
    MainWindow window;

    printf("test point\n");

    return a.exec();
    //return 0;}

«контрольная точка» сначала отображается на экране, а затем в html-коде.


person joker    schedule 09.08.2014    source источник
comment
Вы могли бы записать это в файл?   -  person roelofs    schedule 09.08.2014
comment
Я хотел бы использовать этот код в той же программе, и запись в файл не требуется, достаточно того, что у меня есть данные для записи в источнике QString, но я не могу использовать эту переменную в программе, потому что она получает данные в конце программы.   -  person joker    schedule 09.08.2014


Ответы (1)


Сетевой менеджер работает асинхронно, что означает, что ваш основной поток продолжается сразу после вызова метода get().

Вы можете решить эту проблему, настроив цикл событий, который ожидает завершения загрузки:

  QEventLoop loop;
  connect(networkManager, SIGNAL(finished()), &loop, SLOT(quit()));
  loop.exec(QEventLoop::ExcludeUserInputEvents);

Это должно дать вам ожидаемый результат.

person Fabian    schedule 09.08.2014
comment
Большое спасибо, ваш код решил половину проблемы, но у меня есть несколько вопросов по вашему коду. Почему вы используете SLOT(quit())? Что означает exec(QEventLoop::ExcludeUserInputEvents)? Также у меня странная ситуация, на экране всегда, когда я использую функцию, содержащую цикл, печатается это: QObject::connect: Нет такого сигнала QNetworkAccessManager::finished() в... но после этого программа работает нормально. Хуже всего то, что у меня до сих пор нет доступа к загруженным данным из другой функции. - person joker; 11.08.2014
comment
Слот quit() используется для остановки цикла обработки событий после того, как сетевой менеджер завершит загрузку. В противном случае ваша программа навсегда зависла бы в вызове loop.exec(). Вызов exec() запускает локальный цикл обработки событий. Параметр QEventLoop::ExcludeUserInputEvents сообщает вашему локальному циклу обработки событий, чтобы он не обрабатывал ввод данных пользователем, например ввод с помощью мыши или клавиатуры. Эти входные данные будут доставлены в основной цикл событий после завершения вашего локального цикла, что вам и нужно для такого цикла событий сетевой обработки. - person Fabian; 11.08.2014