【问题标题】:QT Connect QNetworkReply SIGNAL finished() not firingQT Connect QNetworkReply SIGNAL finished() 未触发
【发布时间】:2016-09-28 09:05:49
【问题描述】:

我查看了这个link,除了信号间谍和调试之外,我至少尝试了所有方法。我以this site 为例。我暂时还没有设置调试器。

我的问题是我想触发一个自定义插槽并且什么都没有发生。 我尝试了 qmake 并重建了项目,但结果是一样的。 我在 Windows10 机器上使用带有 QT 5.7 msvc2015_64 的 QTCreator 作为套件。 我没有收到任何应该用于测试功能的未引用警告(*reply not used)。这个问题的根源可能是什么?
我的完成信号有问题吗?

从程序的流程中,我假设它是以下内容:
我创建了一个指向名为 manager 的类 QNetworkAccessManager 的实例的新指针。 然后我将管理器对象的信号finished 连接到来自对象管理器的自定义插槽test(QNetworkReply*)。 现在每次发出来自对象管理器的信号finished 时,都应该执行来自对象管理器的函数test
从文档QNetworReply *QNetworkAccessManager::get(QNetworkRequest(QUrl)) 我假设当这个函数被调用时,一个新的QNetworkReply* 对象被返回,当这个对象完成处理时,finished 信号被发出。我必须以其他方式连接我的信号和插槽吗?

我试图声明QNetworkReply reply* = manager->get....connect(reply, SIGNAL(finished()),this,SLOT(test())); 但在这里我的应用程序崩溃了。

当我设置wireshark和过滤器时: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();

【问题讨论】:

  • 我的 Main.cpp 调用:switch_panel 面板; panel.doDownload();

标签: qt c++11 qt-signals qt-slot qt-connection


【解决方案1】:

Qt 的网络管理器需要一个事件循环来运行,以处理异步网络访问。最简单的方法是在你的 main 中创建一个 QCoreApplication 对象并调用它的 exec() 方法:

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

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    switch_panel p;
    p.doDownload();
    return a.exec();
}

【讨论】:

  • 好吧,我采纳了你的建议并实现了一个事件循环,但以另一种方式:reply = manager->get(QNetworkRequest(QUrl("theuselessweb.com"))); qDebug()
  • Qt 5.5 发出警告,在运行时没有QApplication 就不能使用QEventLoop。它可能有效,但您应该在 main.js 中创建一个实例。不过,您可以为获取请求使用本地事件循环。
  • 另请注意,对loop.exec() 的调用将永远不会返回!您可能希望在您的 switch_panel 类中创建一个 QEventLoop * 并在完成请求后调用 quit() 以恢复执行
  • loop.exec() 确实返回。当finished()信号发出时,loop.exec()之前的connect会导致事件循环退出,使其从exec返回
  • @KevinKrammer 你是对的,我误读了连接...这是一种更优雅的方式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多