QT Connect QNetworkReply SIGNAL завершен () не срабатывает

Я просмотрел эту ссылку а кроме сигнального шпиона и отладки я перепробовал по крайней мере все. Я взял пример с этого сайта. Я пока не устанавливал отладчик.

Моя проблема в том, что я хочу запустить пользовательский слот, и ничего не происходит. Я попробовал qmake и пересобрал проект, но результат был тот же. Я использую QTCreator с QT 5.7 msvc2015_64 в качестве комплекта на машине с Windows10. Я не получаю предупреждений без ссылок, которые должны быть для тестовой функции (*ответ не используется). В чем может быть причина этой проблемы?
Есть ли у меня проблема с готовым сигналом?

Судя по ходу программы, я предполагаю, что это следующее:
я создаю новый указатель на экземпляр класса QNetworkAccessManager с именем manager. Затем я подключаю сигнал объекта-менеджера finished к пользовательскому слоту test(QNetworkReply*) из диспетчера объектов. Теперь каждый раз, когда посылается сигнал finished из диспетчера объектов, должна выполняться функция test из диспетчера объектов.
Из документации QNetworReply *QNetworkAccessManager::get(QNetworkRequest(QUrl)) я предполагаю, что при вызове этой функции возвращается новый объект QNetworkReply*, и когда этот объект завершает обработку finished сигнал испускается. Должен ли я подключать свой сигнал и слот по-другому?

Я попытался объявить QNetworkReply reply* = manager->get.... и connect(reply, SIGNAL(finished()),this,SLOT(test()));, но здесь мое приложение вылетает.

Когда я устанавливаю wireshark и filter: http содержит "http://www.theuselessweb.com", ничего не появляется.

switchwebpanel.h

#ifndef SWITCHWEBPANEL_H
#define SWITCHWEBPANEL_H
#include <QNetworkAccessManager>
#include <QObject>
#include <QUrl>
#include <QNetworkReply>
#include <QFile>
#include <QDateTime>
#include <QNetworkRequest>
#include <QDebug>

class switch_panel : public QObject
{
Q_OBJECT

public:
  switch_panel(QObject *parent = 0);
  void doDownload();

signals:

public slots:
  void replyFinished(QNetworkReply *reply);
  void test(QNetworkReply * reply);

private:
  QNetworkAccessManager *manager;

};

#endif // SWITCHWEBPANEL_H

switchwebpanel.cpp

#include <switchwebpanel.h>


switch_panel::switch_panel(QObject *parent):
QObject(parent)
{}


void switch_panel::doDownload(){
  qDebug()<<"Downloader gestartet";
  manager = new QNetworkAccessManager (this);
  qDebug()<<"connect...";

  // Here i want to call the test(QNetworkReply*) function

  connect(manager, SIGNAL(finished(QNetworkReply*)),
        this, SLOT(test(QNetworkReply*)));
  qDebug()<<"get";
  manager->get(QNetworkRequest(QUrl("http://www.theuselessweb.com")));
  qDebug()<<"manager gegeted";
}

void switch_panel::replyFinished(QNetworkReply *reply){
  qDebug()<<"Async starten";
  if(reply->error()){
    qDebug()<<"error";
    qDebug()<<reply->errorString();
  }
  else {
    qDebug()<<reply->header(QNetworkRequest::ContentTypeHeader).toString();
    qDebug()<<reply->header(QNetworkRequest::LastModifiedHeader).toDateTime().toString();
    qDebug()<<reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
    qDebug()<<"File";
    QFile *file = new QFile("./htmlpanel.txt");
    if(file->open(QFile::Append)){
        file->write(reply->readAll());
        file->flush();
        file->close();
    }
    //delete file;
  }
  reply->deleteLater();
  qDebug()<<"Async fertig";
}
void switch_panel::test(QNetworkReply *reply){
  qDebug()<<"test";
}

Я получаю следующий вывод:

Download
Downloader gestartet
connect...
get
manager gegeted

Мои вызовы Main.cpp: switch_panel panel; panel.doDownload();


person Eggi    schedule 28.09.2016    source источник
comment
Мои вызовы Main.cpp: панель switch_panel; панель.doDownload();   -  person Eggi    schedule 28.09.2016


Ответы (1)


Сетевой менеджер Qt требует запуска цикла обработки событий для обработки асинхронного доступа к сети. Самый простой способ — создать объект QCoreApplication в вашем main и вызвать его метод exec():

#include <QCoreApplication>
#include "switchwebpanel.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    switch_panel p;
    p.doDownload();
    return a.exec();
}
person king_nak    schedule 28.09.2016
comment
Хорошо, я последовал вашему совету и реализовал цикл обработки событий, но по-другому: .com))); qDebug()‹‹connect; Цикл QEventLoop; соединить(ответить,СИГНАЛ(завершено()),&цикл,СЛОТ(выйти())); цикл.exec(); - person Eggi; 28.09.2016
comment
Qt 5.5 выдает предупреждение о том, что QEventLoop нельзя использовать без QApplication во время выполнения. Это может сработать, но вы должны создать экземпляр в файле main. Тем не менее, вы можете использовать локальный цикл обработки событий для своего запроса на получение. - person king_nak; 28.09.2016
comment
Также обратите внимание, что вызов loop.exec() никогда не вернется! Возможно, вы захотите создать QEventLoop * в своем классе switch_panel и вызвать quit(), когда закончите с запросом, чтобы возобновить выполнение. - person king_nak; 28.09.2016
comment
loop.exec() возвращается. Когда испускается сигнал finished(), соединение перед loop.exec() приведет к выходу из цикла обработки событий, что приведет к возврату из exec. - person Kevin Krammer; 28.09.2016
comment
@KevinKrammer Вы правы, я неправильно понял соединение ... Это гораздо более элегантный способ - person king_nak; 29.09.2016