PDA

View Full Version : Qt QNetworkAccessManager and Slot not working in C++



cruzo
28th March 2015, 10:36
i am a beginner in c++ and i am trying to retrieve data from a website using http request and to download the data in a file .

I am using the classes :

QMainWindow QtNetwork/QNetworkAccessManager QtNetwork/QNetworkRequest QtNetwork/QNetworkReply QUrl

The thing is that the file is created but there is no data in the file and i am getting an error that i don't understand . I searched through the forum found some similar kind of problems but did not understand as i am a beginner . Please help me its a school project and i am really stuck here.

Here is the httpWindow.h code



#ifndef HTTPWINDOW_H
#define HTTPWINDOW_H

#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QUrl>
#include <QString>

class QFile;

namespace Ui {
class httpWindow;
}

class httpWindow : public QMainWindow
{
Q_OBJECT

public:
explicit httpWindow(QWidget *parent = 0);
~httpWindow();
void request(QUrl url);

private slots:
void downloadFile();
void httpFinished();
void httpReadyRead();
private:
Ui::httpWindow *ui;
QUrl url;
QNetworkAccessManager *manager;
QNetworkRequest requete;
QNetworkReply *reply;
QFile *file;
int httpGetId;
bool httpRequestAborted;

};

#endif // HTTPWINDOW_H


Here is the httpwindow.cpp


#include <QtWidgets>
#include <qnetwork.h>
#include <QString>

#include "httpwindow.h"
#include "ui_httpwindow.h"

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

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

void httpWindow::request(QUrl url)
{
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished()),
this, SLOT(httpFinished()));

//requete.setUrl(QUrl("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide"));
requete.setUrl(url);

reply = manager->get(requete);
connect(reply, SIGNAL(&reply::readyRead()), this, SLOT(httpReadyRead()));
}

void httpWindow::downloadFile()
{
QMessageBox msg ;
QUrl url("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide") ;
qDebug() << url.toString();
QFileInfo fileInfo(url.path());
//msg.setText("fileInfo = " + fileInfo);
QString fileName = "C:\\testQt\\" + fileInfo.fileName();
msg.setText("fileName = " + fileName);

if (fileName.isEmpty()){

fileName = "C:\testQt\fichier.html";
msg.setText(" création d'un nouveau fichier fichier.html ");

}
if (QFile::exists(fileName)) {
QFile::remove(fileName);
return;


}
file = new QFile(fileName);
msg.setText(" QFile::exists(fileName) == true , file : ");
if (!file->open(QIODevice::WriteOnly)) {

delete file;
file = 0;
return;
}


// schedule the request
httpRequestAborted = false;
request(url);

}

void httpWindow::httpFinished()
{
if (httpRequestAborted) {
if (file) {
file->close();
file->remove();
delete file;
file = 0;
}
reply->deleteLater();
return;
}

file->flush();
file->close();

QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttrib ute);
if (reply->error()) {
file->remove();
// QMessageBox::information(this, tr("HTTP"),
// tr("Download failed: %1.")
// .arg(reply->errorString()));
// downloadButton->setEnabled(true);
} else if (!redirectionTarget.isNull()) {
QUrl newUrl = url.resolved(redirectionTarget.toUrl());
// if (QMessageBox::question(this, tr("HTTP"),
// tr("Redirect to %1 ?").arg(newUrl.toString()),
// QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
url = newUrl;
reply->deleteLater();
file->open(QIODevice::WriteOnly);
file->resize(0);
request(url);
return;

}

reply->deleteLater();
reply = 0;
delete file;
file = 0;

}


void httpWindow::httpReadyRead()
{
// this slot gets called every time the QNetworkReply has new data.
// We read all of its new data and write it into the file.
// That way we use less RAM than when reading it at the finished()
// signal of the QNetworkReply
if (file)
file->write(reply->readAll());

}
Here is the main.cpp code

#include "httpwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
httpWindow w;
w.show();

return a.exec();
}

The errors :


can't find linker symbol for virtual table for `QMessageBox' value
found `RGB_MASK' instead
can't find linker symbol for virtual table for `QMessageBox' value
found `RGB_MASK' instead
"http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide"
QObject::connect: No such signal QNetworkAccessManager::finished() in ..\ppe3_trading_test\httpwindow.cpp:24
QObject::connect: (receiver name: 'httpWindow')
QObject::connect: No such signal QNetworkReplyHttpImpl::&reply::readyRead() in ..\ppe3_trading_test\httpwindow.cpp:31
QObject::connect: (receiver name: 'httpWindow')


Please do help me its really important for my schooling and its been 4 days i am trying to solve the problem .PLease help :crying:

Lykurg
28th March 2015, 12:00
Well, QNetworkAccessManager does have a signal called finished() ... but for the connection you also have to pass the signature :)

cruzo
28th March 2015, 12:54
Plz can you explain further what do you mean by signature ? and in the code i posted i have written this function :


void httpWindow::request(QUrl url)
{
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished()),
this, SLOT(httpFinished()));

//requete.setUrl(QUrl("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide"));
requete.setUrl(url);

reply = manager->get(requete);
connect(reply, SIGNAL(&reply::readyRead()), this, SLOT(httpReadyRead()));
}


Which is used in this download file function :


void httpWindow::downloadFile()
{
QMessageBox msg ;
QUrl url("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide") ;
qDebug() << url.toString();
QFileInfo fileInfo(url.path());
//msg.setText("fileInfo = " + fileInfo);
QString fileName = "C:\\testQt\\" + fileInfo.fileName();
msg.setText("fileName = " + fileName);

if (fileName.isEmpty()){

fileName = "C:\testQt\fichier.html";
msg.setText(" création d'un nouveau fichier fichier.html ");

}
if (QFile::exists(fileName)) {
QFile::remove(fileName);
return;


}
file = new QFile(fileName);
msg.setText(" QFile::exists(fileName) == true , file : ");
if (!file->open(QIODevice::WriteOnly)) {

delete file;
file = 0;
return;
}


// schedule the request
httpRequestAborted = false;
request(url);

}

Do you think the code is right ? I mean do you see somthing that is missing ? I am really new at this please kindly help :(

anda_skoa
28th March 2015, 13:39
Plz can you explain further what do you mean by signature ?

The SIGNAL and SLOT macros need the name of the signal/slot and the types of their arguments.
QNetworkAccessManager's finished() signal as an argument of type QNetworkReply*





connect(reply, SIGNAL(&reply::readyRead()), this, SLOT(httpReadyRead()));


This connect is also wrong, the SIGNAL macro contains more than just the signal's signature.

Cheers,
_

cruzo
28th March 2015, 14:11
ok , so i changed some things in my code in the request () function :

instead of this :
connect(reply, SIGNAL(&reply::readyRead()), this, SLOT(httpReadyRead()));

i changed into this :
connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));

and i added " QNetworkReply* " and it gives this :


connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(httpFinished()));

So in the end i have this code for request ():


void httpWindow::request(QUrl url)
{
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(httpFinished()));

//requete.setUrl(QUrl("http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide"));
requete.setUrl(url);

reply = manager->get(requete);
connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
//connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
//SLOT(onError(QNetworkReply::NetworkError)));
}


This is the code for httpFinished():


if (httpRequestAborted) {
if (file) {
file->close();
file->remove();
delete file;
file = 0;
}
reply->deleteLater();
return;
}

file->flush();
file->close();

QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttrib ute);
if (reply->error()) {
file->remove();

} else if (!redirectionTarget.isNull()) {
QUrl newUrl = url.resolved(redirectionTarget.toUrl());

url = newUrl;
reply->deleteLater();
file->open(QIODevice::WriteOnly);
file->resize(0);
request(url);
return;

}

reply->deleteLater();
reply = 0;
delete file;
file = 0;

}


When i started Debug , i got these errors :


can't find linker symbol for virtual table for `QMessageBox' value
found `RGB_MASK' instead
can't find linker symbol for virtual table for `QMessageBox' value
found `RGB_MASK' instead
"http://fxrates.fr.forexprostools.com/index.php?force_lang=5&pairs_ids=1;3;2;4;7;5;8;6;&header-text-color=%23FFFFFF&curr-name-color=%230059b0&inner-text-color=%23000000&green-text-color=%232A8215&green-background=%23B7F4C2&red-text-color=%23DC0001&red-background=%23FFE2E2&inner-border-color=%23CBCBCB&border-color=%23cbcbcb&bg1=%23F6F6F6&bg2=%23ffffff&bid=show&ask=show&last=show&change=hide&last_update=hide

and the application stucked saying it can not continue so i stopped the debug .

Please help me identify these errors , i am sure you are more knowledge in these than me .