2015-01-07 2 views
2

Я пытаюсь получить веб-страницу с помощью Qt и распечатать ее на экране. Проблема заключается в том, что она всегда печатает« ». Это не будет сделано для сделанного SLOT. Я не знаю, есть ли что-то неправильное в connect(). Код компилируется без ошибок. Пытается не использовать циклы событий.При попытке получить веб-страницу с помощью Qt QNetworkAccessManager он всегда возвращает «

Вот код:

net.h

#ifndef NET_H 
 
#define NET_H 
 

 
#include <QObject> 
 
#include <QtNetwork> 
 
#include <QString> 
 
#include <QDebug> 
 

 
class net : public QObject 
 
{ 
 
    Q_OBJECT 
 
public: 
 
    explicit net(QObject *parent = 0); 
 
    void get_site(QString url); 
 
    QString data; 
 

 
signals: 
 

 
public slots: 
 
    void err(QNetworkReply *); 
 
    void done(QNetworkReply *); 
 

 
private: 
 

 
}; 
 

 
#endif // NET_H

net.cpp:

#include "net.h" 
 

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

 
void net::get_site(QString url) { 
 
    QNetworkAccessManager man; 
 
    QNetworkRequest request; 
 

 
    request.setUrl (QUrl(url)); 
 

 
    connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(done(QNetworkReply*))); 
 
    connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(err(QNetworkReply *))); 
 

 
    man.get (QNetworkRequest(QUrl(url))); 
 
} 
 

 
void net::done(QNetworkReply * reply) { 
 
    data = QString(reply->readAll()); 
 
} 
 

 
void net::err(QNetworkReply * reply) { 
 
    data = QString(reply->errorString()); 
 
}

И main.cp р:

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

 

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

 
    net netobj; 
 
    netobj.get_site("http://stackoverflow.com"); 
 
    qDebug() << netobj.data; 
 
    return a.exec(); 
 
}

+0

«Попытка не использовать событие петли еще.» Ну, есть твоя проблема. Нет никакого способа, которым это когда-либо будет работать, не позволяя циклу событий выполнять свою работу. Поместите контрольные точки в свои слоты и посмотрите, что произойдет. – MrEricSir

+0

Но есть некоторые источники, которые этого не использовали. Я предполагаю, что они используют приложения для выхода из слота. Я не уверен. Я новичок в Qt. – Nve

ответ

0

Ваш экземпляр QNetworkAccessManager выходит из области видимости в конце вашей get_site функции. Согласно Qt docs, одного QNetworkAccessManager должно быть достаточно для всего приложения Qt. Ваш объект должен оставаться вне области действия этой функции, так как, скорее всего, от ответа потребуется больше времени, чем потребуется для завершения этой функции. Сделайте QNetworkAccessManager членом вашего сетевого класса, вместо автоматической переменной local, равной get_site.

Обратите внимание, что вам также необходимо управлять временем жизни объекта QNetworkReply, не используя delete, но используя deleteLater(), иначе вы можете протечь память.

+0

Спасибо. проблема все еще остается. Может быть, есть способ подождать, чтобы получить ответ? Я не знаю, почему он перескакивает до слота до того, как закончится ответ. Или почему он заканчивается до того, как ответ получит контент! – Nve

+0

Если вы поймаете и посмотрите на коды ошибок и строку Qt с ошибкой, он должен сказать вам. Я бы отредактировал сообщение, чтобы показать вам, как, но Nejat написал новый ответ, который показывает, как это сделать. Можете ли вы опубликовать ошибки, которые вы получаете? – orfdorf

+0

Отвечено Nejat. Ошибок нет. Он отлично работает с использованием цикла событий. Поэтому я думаю, проблема в том, что она не ждет ответа. Но я точно не знаю почему. – Nve

1

В коде есть некоторые серьезные проблемы. Во-первых, вы должны иметь QNetworkAccessManager в качестве члена класса в файле .h:

class net : public QObject 
{ 
    ... 
private: 
    QNetworkAccessManager nam; 
}; 

Кроме того, вы не должны соединить finished сигнал с двумя слотами. Ваша get_site функция должна быть как:

void net::get_site(QString url) { 

    QNetworkRequest request; 
    request.setUrl (QUrl(url)); 

    connect (&man , SIGNAL(finished(QNetworkReply*)) ,this, SLOT(done(QNetworkReply*))); 

    man.get (QNetworkRequest(QUrl(url))); 
} 

И вы должны управлять возвращаемый ответ следующим образом:

void net::done(QNetworkReply * reply) { 


    if (reply->error() == QNetworkReply::NoError) 
    { 
     data = QString(reply->readAll()); 
    } 
    else 
    { 
     data = QString(reply->errorString()); 
    } 
} 
+0

Спасибо. Но все та же проблема. Кажется, я должен подождать, чтобы получить ответ, используя цикл событий. Я не мог понять другого пути. – Nve

+0

Я не знаю, почему он перескакивает в слот перед тем, как ответить заканчивается. Или почему он заканчивается до того, как ответ получает контент! – Nve

+0

Вызывает ли ошибка при выходе из строя? I.e 'data = QString (reply-> errorString());' line get выполняется? – Nejat