Название: Классы и их взаимосвязанность
Отправлено: Archa4 от Февраль 10, 2011, 14:35
Вообщем дело такое. Мне надо считать с интернета RSS новости и кинуть их в QListWidget. Я все это смог реализовать, но меня попросили все разбить в разные классы. Вот та часть что не работает: Download_xml.cpp: #include <QtCore> #include <QtGui> #include <QtNetwork> #include "download_xml.h" #include "movie.h" #include "list.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::CanStartAndStopInterfaces;
// 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() { }
list.cpp #include <QtCore> #include <QtGui> #include <QtNetwork> #include "list.h" #include "custom_widget.h" #include "movie.h" #include "download_xml.h"
List::List(QWidget *parent) : QWidget(parent) { //List create listWidget = new QListWidget(this); QString str = "http://www.forumcinemas.lv/rss/xml/movies/"; Download_xml *Nado = new Download_xml(str); QVector<Movie *> new_ml = Nado->ml(); for (int i = 0; i<new_ml.size(); i++) { listWidget->insertItem(i, ""); listWidget->setItemWidget(listWidget->item(i), new Custom_Widget (new_ml[i]->name(), new_ml[i]->date(), new_ml[i]->about(), new_ml[i]->picture())); listWidget->item(i)->setSizeHint(QSize (350,470)); listWidget->setSpacing(1); }
//QVector<Movie *> new_ml = Nado->parseXml(str); QVBoxLayout *layout = new QVBoxLayout(this); QHBoxLayout *hboxLayout = new QHBoxLayout; hboxLayout->addWidget(listWidget); layout->addLayout(hboxLayout);
} Проблема такая: когда в list.cpp я создаю Download_xml *Nado = new Download_xml(str); то он инициализируется, но не доходит до parseXML, так как не возникает ни одного сигнала (ни readyRead, ни requestFinished). Как мне заставить программу сделать этот класс и дождаться данных сигналов (тогда в классе прога дойдет до ParseXML, заполнит _ml и я смогу в list.cpp его скопировать)?
Название: Re: Классы и их взаимосвязанность
Отправлено: SimpleSunny от Февраль 10, 2011, 15:00
В Download_xml создайте сигнал окончания работы. В List слот, присоедините к этому сигналу, и в нем уже заполняйте.
Название: Re: Классы и их взаимосвязанность
Отправлено: Archa4 от Февраль 10, 2011, 15:07
Пробывал - не помогает. Сигналы в Download_xml вообще никак не хотят появлятся...
Название: Re: Классы и их взаимосвязанность
Отправлено: Archa4 от Февраль 10, 2011, 15:24
Я думаю одно из двух: либо я не правильно вызываю Download_xml *Nado = new Download_xml(str); и надо как-то по другому, либо надо переделать как-то сам download_xml, чтобы сигналы стали появлятся...
Название: Re: Классы и их взаимосвязанность
Отправлено: Omg от Февраль 10, 2011, 15:36
может я конечно заблуждаюсь, но может быть объявить соединения сигнала со слатом в хттп, а не в хмл? насколько я помню, сигнал испускается в месте объявления коннекта или емита. Или я заблуждаюсь? Если да, то извините, просто только изучаю программирование. :) Или я не верно понял вопрос? :)
Название: Re: Классы и их взаимосвязанность
Отправлено: Archa4 от Февраль 10, 2011, 15:44
Дело в точ что до этого (когла все было в одном файле, а не в отдельных классах) все работало. Сейчас дело такое, что сигналы readyRead и requestFinished вообще не появляются. Может кто-нибудь смог бы подправить код, или описал, если это может помочь, как юзать QNetworkAccessManager...
Название: Re: Классы и их взаимосвязанность
Отправлено: Omg от Февраль 10, 2011, 15:47
connect(&http, SIGNAL(readyRead(QHttpResponseHeader)), this, SLOT(readData(QHttpResponseHeader)));
connect(&http, SIGNAL(requestFinished(int,bool)), this, SLOT(finished(int,bool))); попробовать переписать в cpp файл где определятся класс объекта http С изменениями конечно же. ^^
Название: Re: Классы и их взаимосвязанность
Отправлено: Archa4 от Февраль 10, 2011, 15:54
попробовать переписать в cpp файл где определятся класс объекта http
Куда переписать? Если логически подумать то сейчас очень правильная расстоновка всех функций...
Название: Re: Классы и их взаимосвязанность
Отправлено: Omg от Февраль 10, 2011, 16:04
Где у вас создается http на который вы ссылаетесь в своих конектах?
Название: Re: Классы и их взаимосвязанность
Отправлено: Archa4 от Февраль 10, 2011, 16:15
Он лежит в: Download_xml.h: #ifndef DOWNLOAD_XML_H #define DOWNLOAD_XML_H
#include <QHttp> #include <QWidget> #include <QBuffer> #include <QXmlStreamReader> #include "movie.h"
#ifdef Q_OS_SYMBIAN // Bearer #include <QNetworkConfigurationManager> #include <QNetworkSession> #include <QPointer>
// QtMobility namespace QTM_USE_NAMESPACE #endif
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 &); void parseXml();
QVector<Movie *> ml() { return _ml; }
signals: void finish();
private:
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 };
#endif // DOWNLOAD_XML_H
|