Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: TaIRou от Октябрь 24, 2012, 20:26



Название: Стартовое окно в процессе запуска основного приложения
Отправлено: TaIRou от Октябрь 24, 2012, 20:26
доброго времени суток!

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

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

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

спасибо.


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: mutineer от Октябрь 24, 2012, 20:42
вызывай периодически QApplication::processEvents()


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: xokc от Октябрь 25, 2012, 06:46
Вообще, для этих целей целый класс есть  - QSplashScreen.
Читать тут http://qt-project.org/doc/qt-4.8/QSplashScreen.html (http://qt-project.org/doc/qt-4.8/QSplashScreen.html)
И, таки-да, регулярный вызов processEvents.

Код
C++ (Qt)
QPixmap pixmap(":/splash.png");
QSplashScreen *splash = new QSplashScreen(pixmap);
splash->show();
 
... // Loading some items
splash->showMessage("Loaded modules");
 
qApp->processEvents();
 
... // Establishing connections
splash->showMessage("Established connections");
 
qApp->processEvents();
 


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: TaIRou от Октябрь 25, 2012, 17:03
Замечательно, спасибо ребят за наводку!


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Alex Custov от Октябрь 25, 2012, 19:51
я думаю, вместо processEvents() достаточно splash->repaint().


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Igors от Октябрь 25, 2012, 21:20
я думаю, вместо processEvents() достаточно splash->repaint().
Это вроде бы кажется бесспорным, но проверка не подтверждает. Запускаем прилагаемый примерчик из консоли, после того как repaint вернуло управление - окно не перерисовано (OSX 10.6.8 )
Код
C++ (Qt)
#include <QtGUI>
 
int thePaintNo = 0;
 
class MyDialog : public QDialog {
public:
virtual void paintEvent( QPaintEvent * )
{
printf("paintEvent %d\n", thePaintNo);
QPainter painter(this);
QRect R(0, 0, 100, 100);
switch (thePaintNo % 3) {
case 0:
painter.fillRect(R, QBrush(Qt::red));
break;
case 1:
painter.fillRect(R, QBrush(Qt::green));
break;
case 2:
painter.fillRect(R, QBrush(Qt::blue));
break;
}
++thePaintNo;
}
};
 
int main( int argc, char** argv )
{
QApplication app(argc, argv);
MyDialog dlg;
dlg.show();
 
printf("before repaint\n");
dlg.repaint();
printf("after repaint\n");
getchar();
 
return app.exec();
}
 


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: mutineer от Октябрь 25, 2012, 21:25
я думаю, вместо processEvents() достаточно splash->repaint().
Это вроде бы кажется бесспорным, но проверка не подтверждает. Запускаем прилагаемый примерчик из консоли, после того как repaint вернуло управление - окно не перерисовано (OSX 10.6.8 )

Repaint у сплешскрина отличается от обычного
Цитировать
void QSplashScreen::repaint ()

This overrides QWidget::repaint(). It differs from the standard repaint function in that it also calls QApplication::flush() to ensure the updates are displayed, even when there is no event loop present.


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Igors от Октябрь 25, 2012, 23:30
Repaint у сплешскрина отличается от обычного
Пробовал и вставлять app.flush() и наследоваться от QSplashScreen, и оба вместе :) Не катит, квадрат красный. Вызываю processEvents - все норм, зеленый


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Alex Custov от Октябрь 25, 2012, 23:31
я думаю, вместо processEvents() достаточно splash->repaint().
Это вроде бы кажется бесспорным, но проверка не подтверждает. Запускаем прилагаемый примерчик из консоли, после того как repaint вернуло управление - окно не перерисовано (OSX 10.6.8 )

Предполагаю потому, что окно всё ещё скрыто в момент repaint(). repaint() нужно звать после каждой установки значения в QProgressDialog, когда он точно видим. У меня что-то подобное есть, только не во время старта, а во время работы программы.


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Igors от Октябрь 26, 2012, 13:44
Предполагаю потому, что окно всё ещё скрыто в момент repaint(). repaint() нужно звать после каждой установки значения в QProgressDialog, когда он точно видим.
Зачем "полагать" если можно просто компильнуть и увидеть то окно с красным квадратом?  :)


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Alex Custov от Октябрь 26, 2012, 14:35
Зачем "полагать" если можно просто компильнуть и увидеть то окно с красным квадратом?  :)

Посмотрел на винде - рисуется красный квадрат, даже если использовать update() и processEvents(). Я спутал с Linux версией, где окно показыватся асинхронно. В макоси окно показывается тоже синхронно, как и в винде? Если да, то понятно, почему рисуется красный квадрат. Обновление окна происходит принудительно и один раз, и paintEvent() вызывается только один раз. Поэтому мы видим красный квадрат.


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Igors от Октябрь 26, 2012, 14:55
Посмотрел на винде - рисуется красный квадрат, даже если использовать update() и processEvents(). Я спутал с Linux версией, где окно показыватся асинхронно. В макоси окно показывается тоже синхронно, как и в винде? Если да, то понятно, почему рисуется красный квадрат. Обновление окна происходит принудительно и один раз, и paintEvent() вызывается только один раз. Поэтому мы видим красный квадрат.
У меня так
1) Убираю repaint или вставляю getchar() перед repaint. Окно показано, квадрат красный. То есть show окно полностью нарисовало

2) Вставляю app.processEvents после repaint. Все норм, зеленый квадрат, paintEvent вызвано дважды

По поводу "синхронно" на OSX - ну не знаю что тут считать синхронным. Но буферирование налицо. Пример: если мое окно закрыто другими, я могу спокойно их отодвинуть, мое окно отрисуется со всем содержимым без всяких вызовов paint (буфер)


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Alex Custov от Октябрь 26, 2012, 15:09
2) Вставляю app.processEvents после repaint. Все норм, зеленый квадрат, paintEvent вызвано дважды

на винде одиножды, квадрат остаётся красным. Собственно в чём проблема, если paintEvent() точно вызывается? А если он вызывается, то QProgressDialog будет нормально отрисован, что с processEvents(), что без.


Название: Re: Стартовое окно в процессе запуска основного приложения
Отправлено: Igors от Октябрь 26, 2012, 15:17
Собственно в чём проблема, если paintEvent() точно вызывается?
Так один раз (в show). Напр если заменить getchar на длинные расчеты - квадрат остается красным и вызов repaint не помогает