Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите разобраться !
Форум на CrossPlatform.RU > Библиотеки > Qt > Qt Ввод/Вывод, Сеть. Межпроцессное взаимодействие
dbx386
Задача:
Получить информацию по ценам на бензин с нескольких сайтов АЭС и записать их в отдельные члены класса для дальнейших вычислений.

Проблема:
Слот 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
Тело слота начинает выполнятся тогда когда был послан сигнал, который связан с данным слотом. И тут не особо важно в каком месте программы были связанны данный сигнал и слот (connect(...)).

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

P. s. Сделайте шрифты поменьше, а то читать не удобно.
Litkevich Yuriy
dbx386, форматируй своё сообщение для людей которые будут читать, а не для себя
dbx386
Цитата(Trisch @ 3.8.2014, 15:49) *
Тело слота начинает выполнятся тогда когда был послан сигнал, который связан с данным слотом. И тут не особо важно в каком месте программы были связанны данный сигнал и слот (connect(...)).

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

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



Ок, тогда логически напрашивается следующий вопрос. сигнал finished(QNetworkReply*) включится тогда когда закончится соеденение с сервером и соответственно вызовет finishedSlot(QNetworkReply*). Как зделать так чтоб программа дождалась окончания соединения с сервером а только потом вызывала нужный слот на этапе создания объекта w. Мне нужно забрать данные с сайта на этапе создания объекта, а не после того как я дождусь окончания finished(QNetworkReply*).
lanz
Вызывайте w.showPriceOkko() в finishedSlot, после получения всех данных.
dbx386
Цитата(lanz @ 3.8.2014, 19:56) *
Вызывайте w.showPriceOkko() в finishedSlot, после получения всех данных.



Я получаю данныые с задержкой в несколько секунд, пока соеденюсь с сервером. метод showPriceOkko() как отладочная печать показывает мне что член класса double okkoGazCost; не смог забрать данные и выводит мусор, только после того как проходит определенное время, после соединения с сервером, exec() перехватывает сигнал finished(QNetworkReply*) и слот finishedSlot(); делает то, что я хочу сделать при создании объекта, в пределах конструктора.
dbx386
Цитата(lanz @ 3.8.2014, 19:56) *
Вызывайте w.showPriceOkko() в finishedSlot, после получения всех данных.



Я получаю данныые с задержкой в несколько секунд, пока соеденюсь с сервером. метод showPriceOkko() как отладочная печать показывает мне что член класса double okkoGazCost; не смог забрать данные и выводит мусор, только после того как проходит определенное время, после соединения с сервером, exec() перехватывает сигнал finished(QNetworkReply*) и слот finishedSlot(); делает то, что я хочу сделать при создании объекта, в пределах конструктора.
Trisch
Может следует запускать showPriceOkko() по таймеру?
lanz
А почему нужно делать это именно в конструкторе? Заведите класс который будет ожидать всех нужных данных, а потом в нем создавайте класс, который этих данных требует.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.