Russian Qt Forum

Qt => Общие вопросы => Тема начата: abr_qt от Август 05, 2011, 01:31



Название: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 05, 2011, 01:31
Имеется функция, которая довольно долго отрабатывает. Она просто-напросто по сети запрашивает некоторое количество информации, отчего отрабатывает до полуминуты. Функция вызывается при старте программы (во время работы проги функция не вызывается).
Имею такой код:

main.h:
Код:
#include <QApplication>
#include "mainform.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
app.setQuitOnLastWindowClosed(true);

MainForm * mainWindow = new MainForm; //QWidget
mainWindow->show();

app.exec();

return 0;
}

mainform.cpp:
Код:
MainForm::MainForm(QWidget * parent)
: QWidget(parent)
{
...;
preload(); //Вот ета функция
...;
}

Проблема в том, что пока не выполнится данная функция, управление к app.exec() не переходит, потому прога не показывает главное окно ровно столько, сколько работает функция. То есть, до полуминуты.
Как сделать так, чтобы форма показалась сразу при запуске, независимо от того, когда была запущена preload()?

Пробовал через привязку к сигналу (connect, emit), через showEvent - всё то же самое.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: LisandreL от Август 05, 2011, 01:44
Очевидно, не вызывать функцию в конструкторе формы ну или вызывать асинхронно.
Вопрос в том, что можно делать с вашей программой пока не выполнился preload(). Можно ли и нужно ли пользователю разрешать интерактив? Или надо только показать главное окно?


Название: Re: Загрузка "долгого" кода при старте
Отправлено: kambala от Август 05, 2011, 01:47
Код
C++ (Qt)
QTimer::singleShot(100, this, SLOT(preload()));
только preload() сделать слотом


Название: Re: Загрузка "долгого" кода при старте
Отправлено: Fess от Август 05, 2011, 05:16
Если приложением можно пользоваться без подгрузки этих данных, то делать запрос асинхронным, выносить в другой поток. Если нет - можно просто поставить QSplashScreen и написать в нем loading... Пусть пользователь ждет.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 05, 2011, 10:37
Код
C++ (Qt)
QTimer::singleShot(100, this, SLOT(preload()));
только preload() сделать слотом
Такая мысль была ;) Просто почему-то метод выглядит костылём. Хотя, если более изящных решений не предложат, воспользуюсь етим ;)

Очевидно, не вызывать функцию в конструкторе формы ну или вызывать асинхронно.
Вопрос в том, что можно делать с вашей программой пока не выполнился preload(). Можно ли и нужно ли пользователю разрешать интерактив? Или надо только показать главное окно?
В принципе, прога информационная. Она просто отображает данные, которые как раз таки подгружаются. Если  они не загрузятся, то прога просто будет бесфункциональна - будет просто пустое главное окно, но я так и задумал - должно появится окно и, по мере подгрузки данных, в нём будет постепенно отображатся полученная инфа.
Асинхронно - ето как?

Если приложением можно пользоваться без подгрузки этих данных, то делать запрос асинхронным, выносить в другой поток. Если нет - можно просто поставить QSplashScreen и написать в нем loading... Пусть пользователь ждет.
А можно поподробнее про поток? QThread я так понимаю?


Название: Re: Загрузка "долгого" кода при старте
Отправлено: Странник от Август 05, 2011, 10:51
откуда preload() данные подгружает?


Название: Re: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 05, 2011, 11:20
откуда preload() данные подгружает?
По сети с сервака. При помощи mysql


Название: Re: Загрузка "долгого" кода при старте
Отправлено: Странник от Август 05, 2011, 15:42
По сети с сервака. При помощи mysql
то есть из БД, все-таки. как-то много данных грузите, работа в автономном режиме идет, что ли? тогда в отдельном потоке выполняйте запрос,  почитайте про QThread и работу с БД в многопоточном окружении.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 06, 2011, 08:26
По сети с сервака. При помощи mysql
то есть из БД, все-таки. как-то много данных грузите, работа в автономном режиме идет, что ли? тогда в отдельном потоке выполняйте запрос,  почитайте про QThread и работу с БД в многопоточном окружении.
От нескольких килобайт до сотни килобайт в секунду. Нет, режим не автономный.
Хорошо, посмотрю мануалы по потокам. Хотя, мне идея с таймером понравилась :)


Название: Re: Загрузка "долгого" кода при старте
Отправлено: Странник от Август 06, 2011, 09:06
От нескольких килобайт до сотни килобайт в секунду. Нет, режим не автономный.
Хорошо, посмотрю мануалы по потокам. Хотя, мне идея с таймером понравилась :)
таймер не спасет от заморозки интерфейса.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 06, 2011, 12:37
От нескольких килобайт до сотни килобайт в секунду. Нет, режим не автономный.
Хорошо, посмотрю мануалы по потокам. Хотя, мне идея с таймером понравилась :)
таймер не спасет от заморозки интерфейса.
Я в цикле загрузки данных ставлю qApp.processEvents() - не подвисает. Хотя, не спорю, что вариант с QThread даже лучше. А как умнее будет сделать? В main.cpp сконструировать форму и в конструкторе создать поток с функцией preload() или поток создать в самом main.cpp? Не получится ли так, что preload() запустится до того, как в конструкторе главного окна инициализируются все переменные? Етого мне не надо.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: Странник от Август 06, 2011, 12:49
Я в цикле загрузки данных ставлю qApp.processEvents() - не подвисает. Хотя, не спорю, что вариант с QThread даже лучше. А как умнее будет сделать? В main.cpp сконструировать форму и в конструкторе создать поток с функцией preload() или поток создать в самом main.cpp? Не получится ли так, что preload() запустится до того, как в конструкторе главного окна инициализируются все переменные? Етого мне не надо.
от подвисания на долго выполняемых запросах не спасает. но если таких нет, то и так пойдет.
поток запускается вызовом слота start(), ничего не мешает вызвать его после инициализации всех переменных.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 06, 2011, 14:30
от подвисания на долго выполняемых запросах не спасает. но если таких нет, то и так пойдет.
Долго подвешивать может только, скорее всего, query.exec() и/или query.next(), которые перекачивают данные с сервака. В остальном там небольшое тело цикла для обработки полученных данных.

поток запускается вызовом слота start(), ничего не мешает вызвать его после инициализации всех переменных.
Ок, наверное тогда попробую его от главной формы создать и там же запустить. Спасибо ;)


Название: Re: Загрузка "долгого" кода при старте
Отправлено: asvil от Август 06, 2011, 14:53
В таймере же делать query.exec(".....LIMIT OFFSET");
А вообще умнее будет не показывать столько информации пользователю. Он что же будет шариться по table view со 1000 строк?


Название: Re: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 07, 2011, 14:41
В таймере же делать query.exec(".....LIMIT OFFSET");
А вообще умнее будет не показывать столько информации пользователю. Он что же будет шариться по table view со 1000 строк?
Там не table view, там посекундная сетевая статистика. Я не могу ставить ни LIMIT, ни OFFSET - статистика нужна вся.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: asvil от Август 07, 2011, 14:53
статистика нужна вся, но вы нехотите чтобы пользователь ждал? противоречиво.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 08, 2011, 10:21
статистика нужна вся, но вы нехотите чтобы пользователь ждал? противоречиво.
Вы меня, наверное, не поняли.
Я не хочу, чтобы пользователь думал, что прога не запускается, ведь главного окна не видно, пока функция не отработает. Потому цель сабжа - отобразить главную форму при старте программы, написать на ней "Загрузка, ждите" и сразу за етим выполнять загрузку данных, а не сократить время отработки кода.


Название: Re: Загрузка "долгого" кода при старте
Отправлено: asvil от Август 08, 2011, 10:27
А сплэшскрин чем не угодил?


Название: Re: Загрузка "долгого" кода при старте
Отправлено: abr_qt от Август 11, 2011, 22:44
А сплэшскрин чем не угодил?
А какая разница? Если его в main.cpp поставить, он тоже до app.exec() не появится (пробовал). Прийдётся тот же самый таймер на 100мс ставить для загрузки формы с preload().


Название: Re: Загрузка "долгого" кода при старте
Отправлено: Fess от Август 14, 2011, 16:38
До app.exec() у вас не обрабатываются события. Соответственно и окно не отрисуется. Нужно делать qApp->processEvents(); после show для сплешскрина.