crossplatform.ru

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

 
Ответить в данную темуНачать новую тему
> Помогите разобраться !
dbx386
  опции профиля:
сообщение 3.8.2014, 13:43
Сообщение #1


Новичок


Группа: Неактивирован
Сообщений: 8
Регистрация: 10.4.2014
Пользователь №: 4101

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




Репутация:   0  


Задача:
Получить информацию по ценам на бензин с нескольких сайтов АЭС и записать их в отдельные члены класса для дальнейших вычислений.

Проблема:
Слот finishedSlot(QNetworkReply*) содержит алгоритм поиска нужной информации по сайту, так же в нем инициализируется одно из полей класса которое должно содержать информацию по цене на топливо. Проблема в том что данный слот по неизвестным мне причинам вызывается уже после того как создался объект класса, в момент return a.exec();


Вопрос:
Почему сначала срабатывает функция showPriceOkko() в main а затем происходит все, что описанно в finishedSlot(). Насколько я представляю последовательность, сначало все что в конструкторе а потом уже все остальное. Хотя у меня есть предположение что connect происходит именно тогда когда у объекта QApplication вызывается метод exec() Какое решение будет лаконичнее всего на ваше авторитетное для меня мнение


Header:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>



#include<QNetworkAccessManager>
#include<QNetworkRequest>
#include<QNetworkReply>
#include<QDebug>
#include<QUrl>

class MainWindow : public QMainWindow
{
    Q_OBJECT

private:
    QNetworkAccessManager* NAManager;
    QNetworkReply* reply;
    QUrl url;

    double okkoGazCost;
    double wogGazCost;
    double shellGazCost;
    double brsmGazCost;

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

void showPriceOkko();

signals:

public slots:
void finishedSlot(QNetworkReply*);

};

#endif // MAINWINDOW_H


------------------------------------------------------------------
CPP:

#include "mainwindow.h"


MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{
    url = "http://www.okko.ua/ru/types-of-fuel";

    NAManager = new QNetworkAccessManager(this);


    connect(NAManager, SIGNAL    (finished(QNetworkReply*)),
           this,      SLOT      (finishedSlot(QNetworkReply*)));

    reply = NAManager->get(QNetworkRequest(url));


}


MainWindow::~MainWindow()
{

}


void MainWindow::showPriceOkko()
{
    qDebug() << "getOKKO: " << okkoGazCost;
}


void MainWindow::finishedSlot(QNetworkReply *)
{
    QString buffer;

        if (reply->error() == QNetworkReply::NoError)
        {
        QByteArray bytes = reply->readAll();
        QString string(bytes);

            for(int i(0); i < string.length(); ++i)
            {
                    if(string[i] == 'g' && string[i + 1] == 'a' && string[i + 2] == 'z')
                    {
                    buffer += string[i+11];
                    buffer += string[i+12];
                    buffer += string[i+13];
                    buffer += string[i+14];
                    break;
                    }
            }
       okkoGazCost = buffer.toDouble();
        qDebug() << "OKKO: " << okkoGazCost;

        buffer.clear();
        }
        else
        qDebug() << "error Connection to OKKO";


     reply->deleteLater();
}

--------------------------------------------------------------------------------------

MAIN:

#include "mainwindow.h"

#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    w.showPriceOkko();

    return a.exec();
}

----------------------------------------------------------
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 3.8.2014, 15:49
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

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




Репутация:   0  


Тело слота начинает выполнятся тогда когда был послан сигнал, который связан с данным слотом. И тут не особо важно в каком месте программы были связанны данный сигнал и слот (connect(...)).

То-есть, программа выполняется, вполне, корректно.
И да, exec() инициализирует обработку событий, и слоты начинают выполняться тогда когда был вызван exec() (если до этого был послан сигнал).

P. s. Сделайте шрифты поменьше, а то читать не удобно.

Сообщение отредактировал Trisch - 3.8.2014, 15:51
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 3.8.2014, 16:05
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


dbx386, форматируй своё сообщение для людей которые будут читать, а не для себя
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
dbx386
  опции профиля:
сообщение 3.8.2014, 17:45
Сообщение #4


Новичок


Группа: Неактивирован
Сообщений: 8
Регистрация: 10.4.2014
Пользователь №: 4101

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




Репутация:   0  


Цитата(Trisch @ 3.8.2014, 15:49) *
Тело слота начинает выполнятся тогда когда был послан сигнал, который связан с данным слотом. И тут не особо важно в каком месте программы были связанны данный сигнал и слот (connect(...)).

То-есть, программа выполняется, вполне, корректно.
И да, exec() инициализирует обработку событий, и слоты начинают выполняться тогда когда был вызван exec() (если до этого был послан сигнал).

P. s. Сделайте шрифты поменьше, а то читать не удобно.



Ок, тогда логически напрашивается следующий вопрос. сигнал finished(QNetworkReply*) включится тогда когда закончится соеденение с сервером и соответственно вызовет finishedSlot(QNetworkReply*). Как зделать так чтоб программа дождалась окончания соединения с сервером а только потом вызывала нужный слот на этапе создания объекта w. Мне нужно забрать данные с сайта на этапе создания объекта, а не после того как я дождусь окончания finished(QNetworkReply*).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 3.8.2014, 19:56
Сообщение #5


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

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




Репутация:   8  


Вызывайте w.showPriceOkko() в finishedSlot, после получения всех данных.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
dbx386
  опции профиля:
сообщение 3.8.2014, 20:32
Сообщение #6


Новичок


Группа: Неактивирован
Сообщений: 8
Регистрация: 10.4.2014
Пользователь №: 4101

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




Репутация:   0  


Цитата(lanz @ 3.8.2014, 19:56) *
Вызывайте w.showPriceOkko() в finishedSlot, после получения всех данных.



Я получаю данныые с задержкой в несколько секунд, пока соеденюсь с сервером. метод showPriceOkko() как отладочная печать показывает мне что член класса double okkoGazCost; не смог забрать данные и выводит мусор, только после того как проходит определенное время, после соединения с сервером, exec() перехватывает сигнал finished(QNetworkReply*) и слот finishedSlot(); делает то, что я хочу сделать при создании объекта, в пределах конструктора.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
dbx386
  опции профиля:
сообщение 3.8.2014, 20:32
Сообщение #7


Новичок


Группа: Неактивирован
Сообщений: 8
Регистрация: 10.4.2014
Пользователь №: 4101

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




Репутация:   0  


Цитата(lanz @ 3.8.2014, 19:56) *
Вызывайте w.showPriceOkko() в finishedSlot, после получения всех данных.



Я получаю данныые с задержкой в несколько секунд, пока соеденюсь с сервером. метод showPriceOkko() как отладочная печать показывает мне что член класса double okkoGazCost; не смог забрать данные и выводит мусор, только после того как проходит определенное время, после соединения с сервером, exec() перехватывает сигнал finished(QNetworkReply*) и слот finishedSlot(); делает то, что я хочу сделать при создании объекта, в пределах конструктора.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 3.8.2014, 23:47
Сообщение #8


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

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




Репутация:   0  


Может следует запускать showPriceOkko() по таймеру?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 5.8.2014, 20:40
Сообщение #9


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

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




Репутация:   8  


А почему нужно делать это именно в конструкторе? Заведите класс который будет ожидать всех нужных данных, а потом в нем создавайте класс, который этих данных требует.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 26.4.2024, 15:13