crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> использование QNetworkAccessManager
eldar85
  опции профиля:
сообщение 11.8.2010, 10:58
Сообщение #1


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


пробую сделать класс для работы на QNetworkAccessManager но нифига не пойму одного, вот сделал такой код:

net.h

#ifndef NET_H
#define NET_H
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include "QtGui"

class network : public QObject
{
Q_OBJECT

public:


network *load(QString url);
network *setRef(QString ref);
network *setPost(QByteArray post);
QString exec();


private:
QString referer;
QString buffer;




QNetworkAccessManager manager;
QNetworkReply *reply;
QString Url;
QUrl apiUrl;
QByteArray postdata;




public slots:
void getReplyFinished();
void readyReadReply();


};



#endif // NET_H


net.cpp

#include "net.h"




network *network::load(QString newUrl)
{
Url = newUrl;
qDebug() << "1 ";
return this;
}

network *network::setRef(QString ref)
{
referer = ref;
return this;
}

network *network::setPost(QByteArray post)
{
postdata = post;
qDebug() << "2";
return this;
}

QString network::exec()
{


// apiUrl = "http://www.forismatic.com/api/1.0/";
//postdata = "method=getQuote&format=xml";
if(postdata != "")
{
QNetworkRequest request;
request.setUrl(QUrl(Url));
reply = manager.post(request, postdata);


connect(reply, SIGNAL(finished()), this, SLOT(getReplyFinished()));
connect(reply, SIGNAL(readyRead()), this, SLOT(readyReadReply()));

}

qDebug() << buffer;
return buffer;
}

void network::getReplyFinished()
{
reply->deleteLater();

}

void network::readyReadReply()
{
buffer = QString::fromUtf8(reply->readAll());




}


ну и сам вызов в главном классе

network *net = new network;


QString xStr = net->load("http://www.forismatic.com/api/1.0/")->setPost("method=getQuote&format=xml")->exec();



qDebug() << xStr;


по идее exec() должен вернуть buffer с данными, он он гад ничего не возращает, причем в слоте

void network::readyReadReply()
{
buffer = QString::fromUtf8(reply->readAll());

}


загрузка производится, но exec() завершается до того как произойдет вывод reply в buffer. В чем же проблема???

Сообщение отредактировал eldar85 - 11.8.2010, 11:00
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.8.2010, 11:19
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2900
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


много недосказано :)

Цитата(eldar85 @ 11.8.2010, 13:58) *
по идее exec() должен вернуть buffer с данными

и присвоить его QString ? А что за буфер, кстати


Цитата(eldar85 @ 11.8.2010, 13:58) *
net->load(...)->setPost(...)->exec();

проверял ли, каждый элемент цепочки вызовов возвращает корректные объекты ?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
eldar85
  опции профиля:
сообщение 11.8.2010, 11:55
Сообщение #3


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


ну exec() возвращает QString, а buffer это QString, он объявляется в net.h
да все работает, единственное что именно exec() завершается и только потом срабатывает слот

void network::readyReadReply()
{
buffer = QString::fromUtf8(reply->readAll());

}


в нем уже есть ответ от сервера, а мне нужно чтобы этот ответ произошел до завершения exec(), чтобы exec() вернул buffer в месте вызова.

в слоте
void network::readyReadReply()
{
buffer = QString::fromUtf8(reply->readAll());
qDebug() << buffer; //получается ответ сервера,но он получается после завершения exec(), а мне нужно чтобы exec() возвращал buffer с ответом сервера

}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.8.2010, 11:56
Сообщение #4


фрилансер
******

Группа: Участник
Сообщений: 2900
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Насколько я понимаю, когда происходит выход из exec, объект уже завершил работу

А это значит, что тебе в network::readyReadReply() нужно отправить сигнал с буфером в объект основного класса
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
eldar85
  опции профиля:
сообщение 11.8.2010, 12:04
Сообщение #5


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


net->load(...)->setPost(...)->exec();
а тут все нормально срабатывает, да проверял, и load() доставляет что нужно и setPost() и exec() принемает все как нужно, единственное он завершается до того как вызовится слот network::readyReadReply() который присвоит QString buffer ответ сервера...

из exec() выход происходит до того как был получен ответ от сервера в network::readyReadReply(), получается в функции основного класса

void MainWindow::start()
{




    network *net = new network;


  
    QString xStr =  net->load("http://www.forismatic.com/api/1.0/")->setPost("method=getQuote&format=xml")->exec();


    
    qDebug() << xStr;

}


уже заканчивается и только потом происходит ответ от сервера.

а мне нужно в start() сделать несколько вызовов и еще парсить и вырезать лишнее в ответе сервера
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.8.2010, 12:07
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2900
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


так тебе асинхронно надо работать. После запуска нужно дождаться сигнала о приходе данных данных, только потом их считать. В структуре твоего кода не копался, сорри, некогда

Сообщение отредактировал Алексей1153 - 11.8.2010, 12:07
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
eldar85
  опции профиля:
сообщение 11.8.2010, 12:13
Сообщение #7


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


а так получается что в start() был сделан вызов load(), setPost(), exec(), они сработали и завершились, потом завершился старт и только потом вызвался слот network::readyReadReply() который вернул ответ сервера...

да я понимаю что асинхронно нужно но вот никак не пойму как это сделать((
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.8.2010, 12:29
Сообщение #8


фрилансер
******

Группа: Участник
Сообщений: 2900
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


eldar85, для асинхронного обмена объект должен жить дольше времени работы с ним. У тебя это выполняется?

Например, объект должен быть членом основного класса

Цитата
ну и сам вызов в главном классе

network *net = new network;
QString xStr = net->load("http://www.forismatic.com/api/1.0/")->setPost("method=getQuote&format=xml")->exec();
qDebug() << xStr;


здесь код должен быть разделён по меньшей мере на 3 части:

1)
процедура создания объекта для асинхронной работы (это может быть и в конструкторе главного класса)
CMainClass::CMainClass(...):...
{
    ...
    network *net = new network;
    ...
}


2) процедура запроса данных
CMainClass::RequestNewData(......)
{
  net->load("http://www.forismatic.com/api/1.0/");
  net->setPost("method=getQuote&format=xml");
  net->exec();
}


3) слот приёма данных
CMainClass::slot_GotNewData(const QString& data)
{
   qDebug() << data;
}


Сообщение отредактировал Алексей1153 - 11.8.2010, 12:31
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
eldar85
  опции профиля:
сообщение 11.8.2010, 12:41
Сообщение #9


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


как же я тогда получу ответ вот сдесь

CMainClass::RequestNewData(......)
{
  net->load("http://www.forismatic.com/api/1.0/");
  net->setPost("method=getQuote&format=xml");
  net->exec();
}


и смогу в этой же функции парсить ответ сервера и делать еще несколько пост запросов с выпарсинными данными из первого запроса?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.8.2010, 13:11
Сообщение #10


фрилансер
******

Группа: Участник
Сообщений: 2900
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


ну дык... как то так:

void network::readyReadReply()
{
    buffer = QString::fromUtf8(reply->readAll());
    emit pMainClassObj->slot_GotNewData(buffer);
}


А для составления требуемого порядка - завести ассоциативный упорядоченный список по времени посылки сообщения
atd::map<время,QString> m_RequestList;

, а так же список для принимаемых сообщений (если надо)
А дальше - логика
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 27.9.2020, 6:22