Ali-RNT Ответов: 2

Qnetworkaccesmanager не излучает сигнал "готово"


Я написал метод для отправки запроса и хранения данных в QString, но кажется, что сигнал никогда не испускается, потому что программа останавливается в точке ожидания сигнала.

Можете ли вы проверить мой код и посмотреть, не ошибаюсь ли я или что-то еще? Я тестировал его с разными URL-адресами (http и https) и 2 разными сетями, так что это не должно быть проблемой.

P. S: Я должен также упомянуть, что при построении (я использую qmake) Я получаю предупреждение:

warning: ‘manager’ may be used uninitialized in this function [-Wmaybe-uninitialized]
     manager->get (QNetworkRequest (QUrl (url)));


Что я уже пробовал:

void ReqProcessor::getUpdates () //send request
{
    QString url = baseURL;
    QNetworkAccessManager *manager = new QNetworkAccessManager;
    QNetworkReply *reply;
    url.append ("getupdates?timeout=100");
    qDebug() << url; //Debug
    reply = manager->get (QNetworkRequest (QUrl (url)));
    connect (manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished()));
    qDebug() << reply->error(); //debug
    while (!ready)
    {
        continue;
    }
    updates = reply->readAll ();
    qDebug() << updates; //Debug
}


void ReqProcessor::replyFinished ()
{
    qDebug() << "Ready";
    ready = 1;
}

2 Ответов

Рейтинг:
2

Shmuel Zang

То finished сигнал и replyFinished у слота разные подписи. Попробуйте определить свой слот с той же сигнатурой, что и ваш сигнал. Что-то вроде:

void ReqProcessor::replyFinished (QNetworkReply* reply)
{
    //...
}

Qt по умолчанию тип подключения является AutoConnection это означает, что если излучаемый сигнал исходит от другого потока, то его слот ставится в очередь и вызывается, когда управление возвращается в цикл событий текущего потока (например, QueuedConnection). Поскольку у вас есть блокирующий цикл в вашем потоке, элемент управления никогда не возвращается в цикл событий потока...

Попробуйте соединить свой слот с DirectConnection Что-то вроде:

connect (manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished()), Qt::DirectConnection);


Ali-RNT

Спасибо за ваш ответ, но он не работает. Кто-то предложил переместить это соединение перед вызовом метода get (), но он тоже не работает.

Shmuel Zang

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

Ali-RNT

Все еще не получалось, но я догадался! Я должен был использовать QEventLoop. следующий ответ расскажет как. Спасибо за ваши предложения.

Shmuel Zang

Ну, трудно догадаться, что у вас были проблемы с отсутствием QApplication или QCoreApplication (это должно быть в другой функции), не видя всего кода. В любом случае, похоже, вам все еще нужно было использовать DirectConnection...

Рейтинг:
11

Ali-RNT

Наконец-то он начал работать с помощью QEventLoop. вот улучшенный код (и этот слот удален, так как он больше не нужен)

void ReqProcessor::getUpdates ()
{
    QString url = baseURL;
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    QNetworkReply *reply;
    QEventLoop loop;
    url.append ("getupdates?timeout=100");
    connect (manager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()), Qt::DirectConnection);
    reply = manager->get (QNetworkRequest (QUrl (url)));
    loop.exec();
    updates = reply->readAll ();
}


И еще одна ошибка заключалась в том, что в моей программе отсутствовало QApplication или QCoreApplication.