PDA

View Full Version : QNetworkAccessManager problem instantiating



hojoff79
31st January 2011, 00:45
I am trying to make a basic program with the QNetworkAccessManager but I cannot create an instance of the QNetworkAccessManager class. In my header file I instanitate it but then I get a host of errors (8 of them) in the constructor and destructor functions when look similar to the following:

in function MainWindow:
undefined reference to '_imp__ZN21QNetworkAccessManagerC1EP7QObject' mainwindow.cpp 6

Here is the header file code

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QUrl>
#include <QFile>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QtNetwork>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

public slots:
void downloadfile();

private:
Ui::MainWindow *ui;
QUrl url;
QNetworkAccessManager manager;
QNetworkReply *reply;
QFile *file;
};

#endif // MAINWINDOW_H


source code


#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::downloadfile(){
url = ui->lineEdit->text();
reply = manager.get(QNetworkRequest(url));
}


Thanks for your help in advance

ChrisW67
31st January 2011, 01:00
Check your PRO file contains this:


QT += network

as outlined in the QtNetwork page

hojoff79
31st January 2011, 01:27
that did do the trick. I got the program working and I added a function meant to download a given web address, open a file and write the html reponse into the file. It appears to be working (not getting any errors) but when I open the created file there is no information inside. here is the source code. Can anyone see what is wrong?

(I've just been putting "http://www.google.com/" into the line before I hit the button)



#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::downloadfile(){
url = ui->lineEdit->text();
reply = manager.get(QNetworkRequest(url));
connect(reply, SIGNAL(readyRead()), this, SLOT(readinfo()));
connect(reply, SIGNAL(finished()), this, SLOT(donegetting()));

ui->label->setText("Label");
}

void MainWindow::readinfo(){
ui->label->setText("Working!");


}

void MainWindow::donegetting(){
ui->label->setText("Finished!");

file = new QFile("hello.html");

if (file->open(QIODevice::WriteOnly)){
ui->label->setText("FILE OPEN!");
}

file->write(reply->readAll());

if (reply->error()){
ui->label->setText(reply->errorString());
}
}

ChrisW67
31st January 2011, 04:54
Which, if any of the debugging messages are shown?

I cannot see the particular problem but here are some things to look at:

You open the file and never close it.
You attempt to write the file even if it does not open.
You have a memory leak with the handling of QFile on the heap. Suggest allocating it on the stack.
You have a memory leak because you do not delete the QNetworkReply returned by the manager. See QNetworkAccessManager docs.
QNetworkReply::error() does not return a bool (works by accident).

hojoff79
31st January 2011, 05:17
There are no errors shown or debugging notes, it compiles perfectly. I tried reading the reply into the label text and that comes up empty as well. So I believe that the problem is with the reply and not with the writing into the file. As for the memory leak ideas, how could I find out if that is the problem or not? Or what fixes could I attempt to see if that is the problem?

ChrisW67
31st January 2011, 09:51
When it runs is your donegetting() slot called? Is it declared as a slot at all?

You fix the memory leak issues by either not allocating on the heap (the QFile) or by using QObject::deleteLater() on the reply object as outlined in the docs.

Try this contrived example:


#include <QtGui>
#include <QtNetwork>
#include <QDebug>

class MainWindow: public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *p = 0): QMainWindow(p) {
QWidget *central = new QWidget(this);
QLabel *label = new QLabel("URL:", this);
edit = new QLineEdit(this);
button = new QPushButton("Go", this);

QVBoxLayout *layout = new QVBoxLayout(central);
layout->addWidget(label);
layout->addWidget(edit);
layout->addWidget(button);

central->setLayout(layout);
setCentralWidget(central);

connect(button, SIGNAL(clicked()), this, SLOT(clicked()));
}
public slots:
void clicked() {
button->setEnabled(false);
QUrl url(edit->text());
reply = mgr.get( QNetworkRequest(url) );
connect(reply, SIGNAL(finished()), this, SLOT(done()));
};

void done() {
button->setEnabled(true);

QByteArray response = reply->readAll();
qDebug() << response;

QFile out("out.txt"); // on the stack and local to here
if (out.open(QFile::WriteOnly)) {
out.write( response );
out.close();
}
reply->deleteLater(); // clean up the reply object
};

private:
QLineEdit *edit;
QPushButton *button;
QNetworkAccessManager mgr;
QNetworkReply *reply;
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

MainWindow m;
m.show();
return app.exec();
}
#include "main.moc"

hojoff79
31st January 2011, 21:45
Ok so when your code worked I went through the code one difference at a time and it turns out that the declaration of the QUrl was somehow invalid and therefore not properly requestiong from the network.

In my original code, the line:
url = ui->lineEdit->text();
did not properly create the QUrl. I'm not sure why this was because I declared the QUrl in the class definition, but when I changed that specific line to:

QString address = lineEdit->text();
QUrl url(address);

It worked fine. Can anyone explain to me why the other declaration was not valid? The specific line from the class definition is under private:

QUrl url;

Thanks for your help in advance.

ChrisW67
1st February 2011, 00:44
What URL are you targeting?

In my example if I use http://www.google.com.au or www.google.com (which HTTP 302 redirects to .au) it works reliably.

If I use http://www.qtcentre.org then it "fails". The reply in this case is HTTP 301 Moved Permanently and the content is empty. For www.yahoo.com.au a similar HTTP 301 is returned but there is some content on the page.

Qt does not seem to follow the 301 redirect, only the 302 (Linux, Qt 4.6.3).

Perhaps someone with more Qt network stuff under their belt can tell us whether this is a bug or a 'feature'.

sana
9th February 2011, 04:59
hi,
i tried ur code but this is the error i' facing
error: ‘class Ui::MainWindow’ has no member named ‘label’
do u ve any solution for this