PDA

View Full Version : Creating pointer to a Class



Archa4
10th February 2011, 08:13
I wrote this code:

QString str = "http://www.forumcinemas.lv/rss/xml/movies/";
Download_xml *Other = new Download_xml(str);
QVector<Movie *> new_ml = Other->ml();
The problem i have found when going through the Debug:
when new_ml is being assigned a value, Other->ml(); is empty.
The thing is, that i thought when i write:
Download_xml *Other = new Download_xml(str);
new class would be automatically created but instead, it is created only after all those 3 lines of code. What's why when I assign the value to new_ml it is empty. How do i assign to new_ml the right value?

FelixB
10th February 2011, 08:16
the problem must be method "ml()". please post that code...

if "Other" was NULL, "Other->ml()" would create an access violation.

Archa4
10th February 2011, 08:53
Here is Download_xml.h:

class Download_xml : public QWidget
{
Q_OBJECT
public:
Download_xml(QString givenAddress, QWidget *parent = 0);
~Download_xml();
QVector<Movie *> _ml;

public slots:
void fetch(QString address);
void finished(int id, bool error);
void readData(const QHttpResponseHeader &);

QVector<Movie *> ml()
{
return _ml;
}

private:
void parseXml();
QXmlStreamReader xml;
QHttp http;
int connectionId;
// FOR XML
QString currentTag;
QString titleString;
QString dateString;
QString aboutString;
QString pictureString;

#ifdef Q_OS_SYMBIAN
// for bearer management
QPointer<QNetworkSession> m_session;
#endif
};

FelixB
10th February 2011, 08:57
please post your constructor code.

Archa4
10th February 2011, 08:58
#include <QtCore>
#include <QtGui>
#include <QtNetwork>
#include "download_xml.h"
#include "movie.h"

Download_xml::Download_xml(QString givenAddress, QWidget *parent) : QWidget(parent)
{

//OS_Symbian
#ifdef Q_OS_SYMBIAN
// Set Internet Access Point
QNetworkConfigurationManager manager;
const bool canStartIAP = manager.capabilities() & QNetworkConfigurationManager::CanStartAndStopInter faces;

// Is there default access point, use it
QNetworkConfiguration cfg = manager.defaultConfiguration();
if (!cfg.isValid() || !canStartIAP)
{
// Available Access Points not found
QMessageBox::warning(this, "Error", "No access point");
return;
}

m_session = new QNetworkSession(cfg);
m_session->open();
m_session->waitForOpened();
#endif

connect(&http, SIGNAL(readyRead(QHttpResponseHeader)),
this, SLOT(readData(QHttpResponseHeader)));

connect(&http, SIGNAL(requestFinished(int,bool)),
this, SLOT(finished(int,bool)));
//fetch(givenAddress);
//fetch("http://rss.news.yahoo.com/rss/yahoonewsroom");
//parseXml(givenAddress);
}

void Download_xml::fetch(QString address)
{
xml.clear();
QUrl url(address);
http.setHost(url.host());
connectionId = http.get(url.path());
}

void Download_xml::readData(const QHttpResponseHeader &resp)
{
if (resp.statusCode() != 200)
http.abort();
else
{
xml.addData(http.readAll());
}
}

void Download_xml::finished(int id, bool error)
{
if (error)
{
QMessageBox::warning(this, "Error", http.errorString());

}
else if (id == connectionId)
{
parseXml();
}


}

void Download_xml::parseXml()
{
bool movies = false;
bool rss = false;
bool movie = false;
bool item = false;
QVector<Movie *> movie_list;

while (!xml.atEnd() && movies == false && rss == false)
{
xml.readNext();
if (xml.isStartElement())
{
currentTag = xml.name().toString();
if (currentTag == "movieList")
movies = true;
if (currentTag == "rss")
rss = true;
}
}
while (!xml.atEnd() && movies == true)
{
xml.readNext();
if (xml.isStartElement())
{
currentTag = xml.name().toString();
if (currentTag == "movie")
movie = true;
}
else if (xml.isEndElement() && movies == true && movie == true)
{
if (xml.name() == "movie")
{
Movie *one_movie = new Movie;
one_movie->setName(titleString);
one_movie->setDate(dateString);
one_movie->setAbout(aboutString);
one_movie->setPicture(pictureString);
movie_list.append(one_movie);
titleString.clear();
dateString.clear();
aboutString.clear();
pictureString.clear();
movie = false;

}

}
else if (xml.isCharacters() && !xml.isWhitespace() && movies == true && movie == true)
{
if (currentTag == "title")
titleString += xml.text().toString();
else if (currentTag == "globalReleaseDate")
dateString += xml.text().toString();
else if (currentTag == "annotation")
aboutString += xml.text().toString();
else if (currentTag == "imageType1")
pictureString += xml.text().toString();
}
}




while (!xml.atEnd() && rss == true)
{
xml.readNext();
if (xml.isStartElement())
{
currentTag = xml.name().toString();
if (currentTag == "item")
item = true;
}
else if (xml.isEndElement() && rss == true && item == true)
{
if (xml.name() == "item")
{
Movie *one_movie = new Movie;
one_movie->setName(titleString);
one_movie->setDate(dateString);
one_movie->setAbout(aboutString);
movie_list.append(one_movie);
titleString.clear();
dateString.clear();
aboutString.clear();
item = false;
}

}
else if (xml.isCharacters() && !xml.isWhitespace() && rss == true && item == true)
{
if (currentTag == "title")
titleString += xml.text().toString();
else if (currentTag == "pubDate")
dateString += xml.text().toString();
else if (currentTag == "description")
aboutString += xml.text().toString();
}
}

if (xml.error() && xml.error() != QXmlStreamReader::PrematureEndOfDocumentError)
{
qWarning() << "XML ERROR:" << xml.lineNumber() << ": " << xml.errorString();
http.abort();
}

_ml = movie_list;

}

Download_xml::~Download_xml()
{
}


Thing is that at the end of compilation, after those 3 lines a wrote above, the _ml fills up with data, but it's already to late, because the new_ml I want to use later is already been assigned an empty value.... I think it has to do something with QHttp or something...

FelixB
10th February 2011, 09:52
in "parseXML", did you check if "movie_list" gets filled with correct values?

why do you need "movie_list"? why don't you fill "_ml" directly?

Archa4
10th February 2011, 10:30
about not filling _ml directly - i will think i will made _ml private argument.
About parseXML - checking movie List is not the biggest problem - when the application is launching - this function does not even start, that's why _ml is empty when i copy it's content. But later the programm goes into this parseXML function, and movie_list does get filled with correct values.

Added after 23 minutes:

SO my question can be altered:
How to make my download_xml class to complete the download, parsing the XML and fill the _ml, and then be able to copy it?

high_flyer
10th February 2011, 10:31
You are filling _ml in parseXml(), but you never call parseXml() in your constructor , so no wonder you _ml stays empty.(which is the wrong place to do what you are doing there any way, but that is another thread).
Try:


QString str = "http://www.forumcinemas.lv/rss/xml/movies/";
Download_xml *Other = new Download_xml(str);
Other->parseXml();
QVector<Movie *> new_ml = Other->ml();

Archa4
10th February 2011, 10:46
I already tried that - the signals readyRead and requestFinished are not emitted, that's why nothing is happening. If i try Other->parseXml(); it wont work, cause at this moment the xml is empty. xml is filled when the function readData is called, and it's called when signal readyRead is emitted. So now my question is - how to make those signals appear?

The thing is that parseXML(); is called after the signal requestFinished is recieved, but i have no idea how to make the program wait for those signals...

high_flyer
10th February 2011, 11:01
Where do you call QHttp::request()?

Archa4
10th February 2011, 11:07
Hm... Do I need to?
Thing is, when this exact code was in the same file as those 3 lines i first wrote, and i wasn't using Object Movie, things were working. I was getting the contents of webpage, and was able to show them...

high_flyer
10th February 2011, 11:13
Hm... Do I need to?
Read the docs for when a readyRead() signal is emitted.


Thing is, when this exact code was in the same file as those 3 lines i first wrote,
What do you mean?
your code is in a class....

Archa4
10th February 2011, 11:17
your code is in a class....

Now it is. But it was working before i moved it into seperate class

The funny thing is - readyRead signal was emitting in the previous version, and i checked it again - there is no QHttp::request() in that code...

high_flyer
10th February 2011, 11:34
Now it is. But it was working before i moved it into seperate class

The funny thing is - readyRead signal was emitting in the previous version, and i checked it again - there is no QHttp::request() in that code...


You probably have a problem with local stack vars getting out of scope... but I don't have the time look very carefully in to your code...

When fetch() gets called?

Archa4
10th February 2011, 11:50
fetch gets called when the class Download_xml being initialized
(last row)

high_flyer
10th February 2011, 12:45
In your post it was commented out.

Archa4
10th February 2011, 12:58
Yeah :)
I tried to get it to work many times in different ways, for example i changed the constructor and did this:

Download_xml *Nado = new Download_xml();
QString str = "http://www.forumcinemas.lv/rss/xml/movies/";
Nado->fetch(str);
But the signals in the Download_xml still are not generated. I simply cannot get it - why, when the whole thing is in one file, signals are generated, but when i moved it to different class Download_xml - those signals stopped working completely