QNetworkAccessManager fails to execute correctly - c++

I am trying to implement http://developer.nokia.com/community/wiki/Creating_an_HTTP_network_request_in_Qt and my code compiles without error but does not function. I have a warning that reply in "QNetworkReply* reply = nam->get(QNetworkRequest(url));" is not being used. I am sure this is my error and I am not setting up my HTTP GET correctly, but I am unsure of how to correct it.
//coreEng.h
#ifndef COREENG_H
#define COREENG_H
#include <QObject>
#include <QNetworkAccessManager>
class coreEng : public QObject
{
Q_OBJECT
public:
//coreEng(QObject);
coreEng(QObject *parent = 0) :
QObject(parent)
{
nam = new QNetworkAccessManager();
}
private slots:
public slots:
void connect();
void url(QNetworkReply *reply);
void finishedSlot(QNetworkReply* reply);
private:
QNetworkAccessManager* nam;
};
#endif // COREENG_H
//coreEng.cpp
"coreeng.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
void coreEng::connect(){
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
}
void coreEng::url(QNetworkReply*){
QUrl url("http://www.nyctelecomm.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void coreEng::finishedSlot(QNetworkReply* reply){
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
}
else
{
}
//delete reply();
}
//main.cpp
#include <QCoreApplication>
#include "coreeng.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
coreEng mConnect;
mConnect.connect();
return a.exec();
}

changed void coreEng::url(QNetworkReply*) to void coreEng::url()
changed void url(QNetworkReply *reply); to void url();
added mConnect.url(); to main.cpp and I could see the http packet with wireshark exit the NIC and begin the session.

Related

Qt LCD display not working

I am trying to make the output of an http get connection stream to an lcd screen (a future http stock ticker), once connected. My code errors with “C:\Qt5\Tools\QtCreator\bin\httpGET\mainwindow.cpp:16: error: no matching function for call to ‘QLCDNumber::display() ui->lcdNumber->display()” I am unsure how to update display() properly
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
nam = new QNetworkAccessManager();
ui->lcdNumber->display(10);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::connect()
{
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
//ui->lcdNumber->display(10);
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(on_pushButton_clicked()));
}
void MainWindow::requestPage(){
QUrl url("http://www.google.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void MainWindow::finishedSlot(QNetworkReply* reply){
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
}
else
{
}
}
void MainWindow::on_pushButton_clicked()
{
connect();
requestPage();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <QNetworkAccessManager>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
public slots:
void connect();
void requestPage();
void finishedSlot(QNetworkReply* reply);
void on_pushButton_clicked();
private slots:
private:
QNetworkAccessManager* nam;
};
#endif // MAINWINDOW_H
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow mConnect;
mConnect.show();
return a.exec();
}
moving display() fixed the lcd output issue.
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
ui->lcdNumber->display(string);
}

Qt unable to access object data from my function

My code compiles error free but the output to a little lcd panel I have should read 22. It reads the number 44 which is the initial value set in the constuctor. It is failing to update to a new value.
It appears MainWindow::finishedSlot(QNetworkReply* reply) is not being accessed and ui->lcdNumber->display(22) does not update the object as expected.
I can confirm that the connection does establish, I have wireshark running and I can see the software try and reach google, but nothing about that LCD I can get working because I cannot access the constructor object.
The purpose of the LCD is to reflect connection information, but right now I am just trying to reach the constructor.
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
#include <QLCDNumber>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
nam = new QNetworkAccessManager();
ui->lcdNumber->display(44);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::connect()
{
qDebug() << "connect";
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(on_pushButton_clicked()));
}
void MainWindow::requestPage(){
QUrl url("http://www.google.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void MainWindow::finishedSlot(QNetworkReply* reply){
qDebug() << "finishedSlot";
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
ui->lcdNumber->display(22);
// if (reply->error() == QNetworkReply::NoError)
// {
// QImageReader imageReader(reply);
// QImage pic = imageReader.read();
// QByteArray bytes = reply->readAll(); // bytes
// QString string(bytes); // string
// ui->lcdNumber->display(22);
//qDebug()<<string;
// }
// else
// {
// }
}
void MainWindow::on_pushButton_clicked()
{
requestPage();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <QNetworkAccessManager>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
public slots:
void connect();
void requestPage();
void finishedSlot(QNetworkReply* reply);
void on_pushButton_clicked();
private slots:
private:
QNetworkAccessManager* nam;
};
#endif // MAINWINDOW_H
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow mConnect;
mConnect.show();
return a.exec();
}
Maybe it's me, but it seems that there's no connection between button clicked signal and on_pushButton_clicked slot.
Final working solution
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
#include <QLCDNumber>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
nam = new QNetworkAccessManager();
//connect2();
//on_pushButton_clicked();
QObject::connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(on_pushButton_clicked()));
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));
ui->lcdNumber->display(66);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::connect2()
{
qDebug() << "connect";
//QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
//this, SLOT(finishedSlot(QNetworkReply*)));
//QObject::connect(nam, SIGNAL(clicked()), this, SLOT(finishedSlot(QNetworkReply* reply)));
//;
}
void MainWindow::requestPage(){
QUrl url("http://www.google.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void MainWindow::finishedSlot(QNetworkReply* reply){
qDebug() << "finishedSlot";
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
ui->lcdNumber->display(11);
qDebug()<<string;
// if (reply->error() == QNetworkReply::NoError)
// {
// QImageReader imageReader(reply);
// QImage pic = imageReader.read();
// QByteArray bytes = reply->readAll(); // bytes
// QString string(bytes); // string
// ui->lcdNumber->display(22);
//qDebug()<<string;
// }
// else
// {
// }
}
void MainWindow::on_pushButton_clicked()
{
requestPage();
//connect();
}

basic QNetworkAccessManager fails to send requestion

There is no error in my code though there is never any request packet hits my server. I run tcpdump port 80 and nothing ever crosses the wire, wireshark says the same.
//coreeng.h
#ifndef COREENG_H
#define COREENG_H
#include <QObject>
#include <QNetworkAccessManager>
class coreEng : public QObject
{
Q_OBJECT
public:
private slots:
public slots:
void connect();
void url();
void finishedSlot(QNetworkReply* reply);
private:
QNetworkAccessManager* nam;
};
#endif // COREENG_H
//coreengine.cpp
#include "coreeng.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
coreEng::coreEng(QObject *parent) :
QObject(parent)
{
}
explicit coreEng(QObject *parent = 0)
{
nam = new QNetworkAccessManager();
}
void coreEng::connect(){
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
}
void coreEng::url(){
QUrl url("http://www.myserver.com");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void coreEng::finishedSlot(QNetworkReply* reply){
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
}
else
{
}
delete reply();
}
//main.cpp
#include <QCoreApplication>
#include "coreeng.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
coreEng mConnect;
mConnect.connect();
return a.exec();
}
You never call coreEng::url() so you never make a request.
I'm also not sure your constructors are correct. Why not just ditch the explicit constructor and create the QNetworkAccessManager in the default constructor?

coreeng.h:7: error: undefined reference to `vtable for coreEng'

I have tried running qmake to rebuild the Makefiles but creator still gives me the same error coreeng.h:7: error: undefined reference to `vtable for coreEng': I am not accessing the class correctly.
//coreeng.h
#ifndef COREENG_H
#define COREENG_H
#include <QDebug>
#include <QObject>
#include <QNetworkAccessManager>
class coreEng : public QObject
{
Q_OBJECT
public:
explicit coreEng(QObject *parent = 0);
private slots:
public slots:
void connect();
void url();
void finishedSlot(QNetworkReply* reply);
private:
QNetworkAccessManager* nam;
};
#endif // COREENG_H
//coreeng.cpp
#include "coreeng.h"
#include <QNetworkAccessManager>
#include <QUrl>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QImageReader>
coreEng::coreEng(QObject* parent) :
QObject(parent)
{
}
void coreEng::connect(){
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
}
void coreEng::url(){
QUrl url("http://www.forum.nokia.wiki");
QNetworkReply* reply = nam->get(QNetworkRequest(url));
}
void coreEng::finishedSlot(QNetworkReply* reply){
QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (reply->error() == QNetworkReply::NoError)
{
QImageReader imageReader(reply);
QImage pic = imageReader.read();
QByteArray bytes = reply->readAll(); // bytes
QString string(bytes); // string
}
else
{
}
delete reply;
}
//main.cpp
#include <QCoreApplication>
#include <coreeng.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
coreEng mConnect;
mConnect.connect();
return a.exec();
}
This appears to be a GUI error.
restarted creator and this particular situation went away.

How can i download file from the internet in Qt?

I don't know what the problem is...The compiler (Qt) runs program without errors, but the file is not downloaded...
Can you tell me please tell what is wrong?
I made by example "download", which is located in the qt folder. The only difference is that they have is a console, and I have windows application.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtNetwork>
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
class DownloadManager: public QObject
{
Q_OBJECT
QNetworkAccessManager manager;
QList<QNetworkReply *> currentDownloads;
public:
DownloadManager();
void doDownload(const QUrl &url);
QString saveFileName(const QUrl &url);
bool saveToDisk(const QString &filename, QIODevice *data);
public slots:
void execute();
void downloadFinished(QNetworkReply *reply);
};
#endif // MAINWINDOW_H
main.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QtNetwork>
#include <QNetworkAccessManager>
#include <QStringList>
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QStringList>
#include <QTimer>
#include <QUrl>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
#if defined(Q_WS_S60)
w.showMaximized();
#else
w.show();
#endif
return a.exec();
}
DownloadManager::DownloadManager()
{
connect(&manager, SIGNAL(finished(QNetworkReply*)),
SLOT(downloadFinished(QNetworkReply*)));
}
void DownloadManager::doDownload(const QUrl &url)
{
QNetworkRequest request(url);
QNetworkReply *reply = manager.get(request);
currentDownloads.append(reply);
}
QString DownloadManager::saveFileName(const QUrl &url)
{
QString path = url.path();
QString basename = QFileInfo(path).fileName();
if (basename.isEmpty())
basename = "download";
if (QFile::exists(basename)) {
// already exists, don't overwrite
int i = 0;
basename += '.';
while (QFile::exists(basename + QString::number(i)))
++i;
basename += QString::number(i);
}
return basename;
}
bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
{
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
fprintf(stderr, "Could not open %s for writing: %s\n",
qPrintable(filename),
qPrintable(file.errorString()));
return false;
}
file.write(data->readAll());
file.close();
return true;
}
void DownloadManager::execute()
{
QStringList args = QCoreApplication::instance()->arguments();
args[0]="http://www.google.ru/images/srpr/logo3w.png";
QString arg=args[0];
QUrl url = QUrl::fromEncoded(arg.toLocal8Bit());
doDownload(url);
}
void DownloadManager::downloadFinished(QNetworkReply *reply)
{
QUrl url = reply->url();
if (reply->error()) {
fprintf(stderr, "Download of %s failed: %s\n",
url.toEncoded().constData(),
qPrintable(reply->errorString()));
} else {
QString filename = saveFileName(url);
if (saveToDisk(filename, reply))
printf("Download of %s succeded (saved to %s)\n",
url.toEncoded().constData(), qPrintable(filename));
}
currentDownloads.removeAll(reply);
reply->deleteLater();
if (currentDownloads.isEmpty())
// all downloads finished
QCoreApplication::instance()->quit();
}
mainwindow.cpp
#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::on_pushButton_clicked()
{
DownloadManager manager;
manager.execute();
QTimer::singleShot(0, &manager, SLOT(execute()));
}
The problem is at that point of your code:
void MainWindow::on_pushButton_clicked()
{
DownloadManager manager;
manager.execute();
}
QNetworkAccessManager is asynchronous, so it needs an event loop to do any downloading. But when the function on_pushButton_clicked() returns and gives the control back to the event loop, the QNetworkAccessManager is already destroyed, and didn't have the time to do anything.
When you add a QMessageBox in DownloadManager::execute, you are in fact running another event loop withing the slot on_pushButton_clicked(), and it gives the opportunity to the QNetworkAccessManager to do its work.
The correct solution would be to allocate DownloadManager dynamically, and eventually to make it destroy itself when it has finished all downloads.
void MainWindow::on_pushButton_clicked()
{
DownloadManager *manager = new DownloadManager(this);
manager->execute();
}
void DownloadManager::downloadFinished(QNetworkReply *reply)
{
...
if (currentDownloads.isEmpty())
this->deleteLater();
}