QT C ++ - 需要QNetworkAccessManager帮助!阶级问题

时间:2011-08-25 14:16:25

标签: c++ qt qtnetwork

我正在尝试从服务器下载一个页面到我的QT程序,但我一直在寻找方法来实现它并且它们并没有真正起作用。我不是QT / C ++的专家,所以要善良:)

嗯..到目前为止,我带来了这段代码:

[旧代码] - 检查更新后的代码!

http.cpp

#include "http.h"

http::http(QObject *parent) :
    QObject(parent)
{

    qDebug() << "HTTP ST";

    http1 = new QHttp(this);
    connect(http1, SIGNAL(done(bool)), this, SLOT(httpdown())); // Correction 1.
    http1->setHost("localhost");
    http1->get("/test.php");

    qDebug() << "HTTP END";


}

void http::httpdown()
{

    qDebug() << "completed!";
    qDebug() << http1->readAll();


}

http.h

#ifndef HTTP_H
#define HTTP_H

#include <QtNetwork>
#include <QHttp>
#include <QDebug>
#include <QObject>

class http : public QObject
{
    Q_OBJECT
public:
    explicit http(QObject *parent = 0);

signals:

public slots:
    void httpdown();

private:
    QHttp *http1;

};

#endif // HTTP_H

问题是httpdown()永远不会被调用,我已经尝试过任何我知道的事情:(可能我没有正确地做到这一点。

非常感谢帮助。 感谢。


问题更新

我听到了 alexisdm 的建议并检查了QNetworkAccessManager。所以这里是正确处理main()的新代码。

当我从另一个班级运行时,我从未收到信号。

[新代码]

http2.cpp

#include "http2.h"

http2::http2(QObject *parent) :
    QObject(parent)
{
    m_manager = new QNetworkAccessManager(this);
    connect(m_manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(httpdown(QNetworkReply*)));

    QNetworkRequest request;
    request.setUrl(QUrl("http://localhost/test.php"));
    request.setRawHeader("User-Agent", "MyOwnBrowser 1.0");

    m_manager->get(request);
}

void http2::httpdown(QNetworkReply* result)
{

       QByteArray data= result->readAll();
       QString str(data);

       qDebug() <<  str;

}

http2.h

#ifndef HTTP2_H
#define HTTP2_H

#include <QObject>
#include <QDebug>
#include <QtNetwork>
#include <QNetworkReply>

class http2 : public QObject
{
    Q_OBJECT
public:
    explicit http2(QObject *parent = 0);

signals:

public slots:
    void httpdown(QNetworkReply* result);
private:
    QNetworkAccessManager* m_manager;

};

#endif // HTTP2_H

现在,如果我直接在main.cpp下调用它,就像这样:

的main.cpp

#include <QtCore/QCoreApplication>
#include "tcpserver.h"
#include "http2.h"

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

    http2 h; // --> Working!!

    tcpserver mServer;

    return a.exec();
}

工作正常。但是,如果我在tcpserver类中调用它,如下所示:

tcpserver.cpp

#include "tcpserver.h"
#include "protocol.h"
#include "http2.h"

QTextStream in(stdin);

tcpserver::tcpserver(QObject *parent) :
    QObject(parent)
{
    server = new QTcpServer(this);

    [ ... Other Server Stuff ... ]

    // http2 h; // --> OLD CODE - Not Working :(

    http2 *h = new http2(this); // **--> NEW CODE working provided by alexisdm**

}

信号永远不会发生......怎么了?我是新来的! :P

无论如何, alexisdm说:“也许http对象在发出信号之前就被破坏了(例如,如果它被分配在堆栈上)” - 解决方案被接受,代码如下更正请阅读:QT C++ - QNetworkAccessManager help needed! Class problem(链接回答)

我应该怎么做才能避免这种情况?

谢谢! ;)

2 个答案:

答案 0 :(得分:1)

该行:

SIGNAL(bool)

看起来真的不对;你的意思是

SIGNAL(done(bool))

在调试模式下,应该有一些调试输出,说它无法连接信号。

答案 1 :(得分:1)

您的httphttp2对象在构造函数的末尾被销毁,因为它是在本地分配的。

你至少应该动态分配它:

http2 *h = new http2(this);

如果要重复使用它,还可以将其声明为tcpserver的成员,而不是使用局部变量。如果没有,你应该在不再需要时以某种方式销毁它。


修改

  • 如果在插槽内完成销毁和/或响应来自h的信号,则应使用QObject::deleteLater而不是立即删除,因为对象可能仍会被引用信号发射时的某个地方。
    因此,deleteLater();中的httpdown()h->deleteLater();广告位中的tcpserver

  • 要知道您是否有答案或错误,可以使用that code并使用自定义信号和插槽将数据或错误转发到tcpserver类)。