PDA

View Full Version : QNetworkAccessManager Finished() Error



ttimt
23rd February 2014, 16:33
Hello again, my signal and slot are not running



#include "loginthread.h"
#include <QtCore>
#include <QtGui>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <loginwait.h>

loginThread::loginThread()
{
}

void loginThread::run()
{
QNetworkAccessManager *login = new QNetworkAccessManager();

QNetworkRequest request;
request.setUrl(QUrl(server));
request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36");

qDebug() << "here!" << "server is : " << server;
QNetworkReply *reply = login->get(request);

// Some testing only
qDebug() << "got request!!!!";
//readdata(reply);

// This won't run!
connect(login, SIGNAL(finished(QNetworkReply*)), this, SLOT(readdata(QNetworkReply*)));
}


void loginThread::readdata(QNetworkReply *reply)
{
if (reply->error() == QNetworkReply::NoError)
{
qDebug() << "start to read!!!";
QByteArray homepage = reply->readAll();
qDebug() << homepage;
qDebug() << "reading done! readall size :" << homepage.size();
reply->deleteLater();
}else
{
qDebug() << "eerror!";
emit networkreplyError(QString(reply->errorString()));
}
}

Header file :


#ifndef LOGINTHREAD_H
#define LOGINTHREAD_H
#include <QtCore>
#include <QtNetwork/QNetworkReply>

extern QString server;

class loginThread: public QThread
{
Q_OBJECT

public:
loginThread();
void run();

private slots:
void readdata(QNetworkReply *reply);

signals:
void networkreplyError(QString);

};

#endif // LOGINTHREAD_H


I did add http:// infront of the url.

If i run readdata(reply) as shown above for some test, readdata() did run, but it shows size 0.
But the real thing is the connect() won't execute readdata(), I even tried to do :



QNetworkRequest *request = new QNetworkRequest();

some forums thread said object ended too fast, I did made QNetworkAccessManager like this, so I tried this as well, but still the same.

for qDebug, it did shows "got request" and if I didn't comment out readdata(), it will also shows "start to read", "reading done, size 0"

is my problem related with the 'this' ? or something else?
thx.



EDIT:

I tried to change to code to this, still not working, only shows got request


qDebug() << "here!" << "server is : " << server;
//removed this. QNetworkReply *reply =
login->get(*request);
qDebug() << "got request!!!!";
connect(login, SIGNAL(finished(QNetworkReply*)), this, SLOT(readdata(QNetworkReply*)));


or



loginThread *w = new loginThread();
connect(login, SIGNAL(finished(QNetworkReply*)), w, SLOT(readdata(QNetworkReply*)));

stampede
23rd February 2014, 20:01
Try without the separate thread, I don't think you need to launch a thread just to complete a login request.

anda_skoa
23rd February 2014, 20:50
You forgot to run the thread's event loop in run()



void loginThread::run()
{
QNetworkAccessManager *login = new QNetworkAccessManager();

QNetworkRequest request;
request.setUrl(QUrl(server));
request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36");

qDebug() << "here!" << "server is : " << server;
QNetworkReply *reply = login->get(request);

connect(login, SIGNAL(finished(QNetworkReply*)), this, SLOT(readdata(QNetworkReply*)));

exec(); // <--- you forgot this
}


In readdata() you will then want to quit() the thread's event loop so that it finishes and exits run()

And as stampede said: you probably don't need a thread there anyway, usually only makes things more complicated and less efficient.

Cheers,
_

ttimt
24th February 2014, 07:39
Thanks, it's working. Didn't know about event loop is QThread.

Also suddenly, I can't do this anymore
In header file:


loginwait *loginwaitw;

It suddenly shows ISO C++ forbidden, I don't have this problem when using this method before.
I moved that line of code to cpp file and it's working again.


Some sites work and outputted source code, but if i enter http://google.com, it only shows

reading done! readall size : 136191 but not the source code?

anda_skoa
24th February 2014, 08:33
Thanks, it's working. Didn't know about event loop is QThread.

Most of Qt's I/O classes are event loop driven to provide, i.e. non-blocking access without the need for threads.
The classes can of course be used in threads, but then these threads need to run an event loop, just like the main thread does due to QCoreApplication::exec()



Also suddenly, I can't do this anymore
In header file:


loginwait *loginwaitw;

It suddenly shows ISO C++ forbidden, I don't have this problem when using this method before.
I moved that line of code to cpp file and it's working again.

Without the exact error message it is hard to guess what is happening, most likely you forgot the forward declaration for the class so it si an unknown type as far as the compiler is concerned.



Some sites work and outputted source code, but if i enter http://google.com, it only shows
but not the source code?

The content seems to be there, so maybe something is interfering with the debug printing.
You could try writing it to a file and looking at that with a text editor.

Cheers,
_

ttimt
24th February 2014, 09:18
The QFile did work. Maybe output is too long I guess. ;)



Without the exact error message it is hard to guess what is happening, most likely you forgot the forward declaration for the class so it si an unknown type as far as the compiler is concerned.

error: ISO C++ forbids declaration of 'login' with no type
error: expected ';' before '*' token


#include "login.h"
public:
login *loginw;


Maybe because the name QT got confused

anda_skoa
24th February 2014, 09:21
From your code snippets above I'd say your class is called loginThread, not login.

Cheers,
_

ttimt
24th February 2014, 10:30
Here's the thing :

I got 3 class, login, loginThread and loginwait.
In loginwait.h, i included loginThread :


public:
explicit loginwait(QWidget *parent = 0);
~loginwait();
loginThread *loginthreadw;


Compiled and no errors, now again in loginwait.h I add this line just below the last line above, and included the login.h header

login *loginw;

Compile and it shows
error: ISO C++ forbids declaration of 'login' with no type
error: expected ';' before '*' token

In loginwait.cpp :


loginthreadw = new loginThread();
loginthreadw->start();
/*and*/
loginw = new login();
loginw->show();

And so i took the login *loginw; from header file and put it into cpp file just above new login() only it works, no error.




Also, do I need to manually store and send cookies when I'm using QNetworkAccessManager? Or it's automated.:confused:

anda_skoa
24th February 2014, 12:40
Here's the thing :

I got 3 class, login, loginThread and loginwait.
In loginwait.h, i included loginThread :


public:
explicit loginwait(QWidget *parent = 0);
~loginwait();
loginThread *loginthreadw;


Compiled and no errors, now again in loginwait.h I add this line just below the last line above, and included the login.h header

login *loginw;

Compile and it shows
error: ISO C++ forbids declaration of 'login' with no type
error: expected ';' before '*' token

In loginwait.cpp :


loginthreadw = new loginThread();
loginthreadw->start();
/*and*/
loginw = new login();
loginw->show();

And so i took the login *loginw; from header file and put it into cpp file just above new login() only it works, no error.


You don't need to include login.h or loginthread.h in loginw.h if you only declare pointers. Forward declarations work as well



class login;
class loginThread;

class loginw
{
private:
login *loginw;
loginthread *loginthreadw;
};




Also, do I need to manually store and send cookies when I'm using QNetworkAccessManager? Or it's automated.:confused:

QNetworkAccessManager uses a QNetworkCookieJar object to handle cookies. The default implementation of that stores cookies only in memory. If you need persistant storage you need to implement it on top of that.
The documentation of QNetworkCookieJar says : "If you want to save the cookies, you should derive from this class and implement the saving to disk to your own storage format."

Cheers,
_

ttimt
25th February 2014, 09:30
How bout sending cookies? If I use same object of QNetworkaccess manager, and, I interact some web and they sent me cookie that I need to send back
Is it automated? Like sending and setting received cookies etc..



Others are working fine. Also noticed I forgot to disconnect.
Gave a thanks :D

anda_skoa
25th February 2014, 13:21
Yes, I think cookie handling is automatic.

Cheers,
_