crossplatform.ru

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

5 страниц V  < 1 2 3 4 5 >  
Ответить в данную темуНачать новую тему
> [Qt 4.5.0] QHttp и QProgressDialog, странное поведение
Litkevich Yuriy
  опции профиля:
сообщение 18.6.2009, 17:55
Сообщение #21


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

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

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




Репутация:   94  


с сеткой ещё не разу не работал, поэтому ничего петнего не скажу.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 18.6.2009, 17:59
Сообщение #22


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

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

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




Репутация:   34  


Вообще мне интересно влияет ли скорость скачивания файлов от количества оверхеда в методе downloadProgress или нет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 18.6.2009, 18:04
Сообщение #23


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

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

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




Репутация:   94  


Цитата(SABROG @ 18.6.2009, 21:59) *
от количества оверхеда
а как это по-русски?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 18.6.2009, 18:42
Сообщение #24


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

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

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




Репутация:   34  


Цитата(Litkevich Yuriy @ 18.6.2009, 19:04) *
Цитата(SABROG @ 18.6.2009, 21:59) *
от количества оверхеда
а как это по-русски?


Грубо говоря, если я в этом методе поставлю while(1) насколько скорость скачивания файла упадет, или остановится совсем?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Авварон
  опции профиля:
сообщение 18.6.2009, 22:12
Сообщение #25


Студент
*

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

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




Репутация:   0  


бтв у меня программа выдавала double free при юзании progress dialog exec() при этом крашилась не всегда... при show() все ок было... грешил на нити, но не понятно где и почему - там данные независимо обрабатывались...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 19.6.2009, 18:00
Сообщение #26


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

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

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




Репутация:   34  


Цитата(SABROG @ 18.6.2009, 13:05) *
Переделал код на этот и все работает отлично:


Немного поспешил с выводами, теперь косяк перебрался с прогресса на сигналы readyRead. Теперь они пропадают и как следствие файл сохраняется битым.

Из лога понятно, что скаченный xml файл пытается отпарсится раньше, чем приходит последний кусок, а именно сигнал finished() приходит раньше, чем последний сигнал readyRead:

10220
20440
13804
5544
2772
"Parse error at line 16951, column 4:
unexpected end of file"
4989


Еще при таком раскладе таже ошибка возникает:

progressDialog->setModal(true);

---
Я воспроизвел баг:

#include <QtCore/QtGlobal>
#include <QtCore/QtDebug>
#include <QtCore/QUrl>
#include <QtGui/QApplication>
#include <QtGui/QProgressDialog>
#include <QtGui/QPushButton>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>

class MyWidget : public QWidget
{
    Q_OBJECT;
public:
    MyWidget(QWidget *parent = 0) : QWidget(parent), button(this)
                                    , progressDlg(this)
                                    , netmanager(this)
    {
        button.setText(tr("Download"));
        progressDlg.setRange(1, 100);
        progressDlg.setModal(true);
        connect(&button, SIGNAL(clicked(bool)), this, SLOT(buttonClicked(bool)));

    }
public slots:
    void buttonClicked(bool checked = false)
    {

        QNetworkReply *reply = netmanager.get(
                QNetworkRequest(
                QUrl(
                QLatin1String(
                "http://www.qtsoftware.com/files/pdf/qt-4.4-whitepaper"
                ))));
        connect(reply, SIGNAL(downloadProgress(qint64, qint64)),
                this, SLOT(dataReadProgress(qint64, qint64)));
        connect(reply, SIGNAL(readyRead()),
                this, SLOT(dataReadyRead()));
        connect(&netmanager, SIGNAL(finished(QNetworkReply *)),
                this, SLOT(finished(QNetworkReply *)));

        progressDlg.exec();
        //progressDlg.show();
    }
    void dataReadProgress(qint64 done, qint64 total)
    {
        qDebug() << done << total;
        progressDlg.setMaximum(total);
        progressDlg.setValue(done);
    }
    void dataReadyRead()
    {
        QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
        qDebug() << reply->bytesAvailable();
    }
    void finished(QNetworkReply *reply)
    {
        qDebug() << "finished";
    }
private:
    QPushButton button;
    QProgressDialog progressDlg;
    QNetworkAccessManager netmanager;
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MyWidget widget;
    widget.show();
    return a.exec();
}

#include "main.moc"


Вот логи:

3634106 3664786
3634106
3638202 3664786
3638202
3640838 3664786
3640838
3647206 3664786
3647206
3654586 3664786
3654586
3658682 3664786
3658682
3664786 3664786
finished
3664786


Сообщение отредактировал SABROG - 19.6.2009, 18:55
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 19.6.2009, 21:10
Сообщение #27


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

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

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




Репутация:   44  


Цитата(SABROG @ 19.6.2009, 19:00) *
Я воспроизвел баг:

+1
Такое же поведение.

Но если поменять местами коннекты, т.е. сначала подключить сигнал finished, а потом readyRead, то все начинает работать. :)

Сообщение отредактировал BRE - 19.6.2009, 21:12
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 20.6.2009, 1:56
Сообщение #28


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

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

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




Репутация:   94  


Цитата(BRE @ 20.6.2009, 1:10) *
Но если поменять местами коннекты,
очень интересное наблюдение.
Они, что асинхронно подключаются? Хм.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 20.6.2009, 5:53
Сообщение #29


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

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

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




Репутация:   44  


Цитата(Litkevich Yuriy @ 20.6.2009, 2:56) *
Цитата(BRE @ 20.6.2009, 1:10) *
Но если поменять местами коннекты,
очень интересное наблюдение.
Они, что асинхронно подключаются? Хм.

Сейчас нет времени проверить, но вроде при конекте, все получатели сигнала заносятся в список и при emit'е вызываются согласно этого списка. Думаю в этом причина.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 20.6.2009, 8:30
Сообщение #30


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

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

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




Репутация:   34  


В документации о сигналах и слотах написано:

Цитата
If several slots are connected to one signal, the slots will be executed one after the other, in an arbitrary order, when the signal is emitted.


Но тут я понимаю, один и тот же сигнал и несколько слотов. А вот почему меняется порядок вызовов слотов для двух совершенно разных сигналов - непонятно. Не исключаю, что порядок connect'ов может влиять на ситуацию, но это такое же откладывание существующей проблемы как и show вместо exec. В варианте с QHttp сначала приходил сигнал finished(), а потом сигнал dataReadProgress. Но т.к. сам сигнал информационный и безобидный, то с этим еще как-то можно жить, а вот когда приходит сигнал readyRead и слот пытается записать данные в файл, который уже закрыт и указатель стал уже не валидным, вот тут программа и падает. И виной всему этому, казалось бы безобидный, QProgressBar, который я решил добавить для удобство пользователя. Маленькие причины - большие последствия.

Проверил на Qt 4.6, там ситуация еще хуже. Помимо того, что есть баг с неправильным порядком вызовов слотов, так там с каждым новым скачиванием приходит на 1 больше сигналов finished(). Т.е. если я скачаю файл 10 раз, то в конце скачки десятого раза придет 10 сигналов finished() + последним может прийти сигнал readyRead после них. Тролли молчат второй день, наверно выходные.
---

Моя ошибка, тут каждый раз один и тот же сигнал добавляется к предыдущему:

    void buttonClicked(bool checked = false)
    {
       connect(&netmanager, SIGNAL(finished(QNetworkReply *)),
                this, SLOT(finished(QNetworkReply *)));


Переделал на

connect(reply, SIGNAL(finished()), this, SLOT(finished()))


Но проблема с тем, что слот finished вызывается предпоследним осталась.

Сообщение отредактировал SABROG - 22.6.2009, 17:42
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 15.1.2025, 2:05