IT Notes

QSplashScreen: Начальный экран-заставка для Qt-приложения

Если приложение запускается слишком долго, то пользователь может решить, что оно не работает вовсе. Чтобы снять такие опасения, принято использовать экраны-заставки, называемые Splash Screen. Подобные заставки вы могли видеть при запуске Eclipse, Visual Studio, Adobe Photoshop и других известных программ.

Экраны заставки решают две задачи:

  1. Показывают, что приложение действительно работает и запускается;
  2. Дают примерную оценку готовности приложения к работе.

Создадим свой Splash Screen для Qt-приложения с помощью QSplashScreen. В результате получим следующее:

splash-screen-loading-thumbnail

QSplashScreen представляет собой достаточно примитивный виджет, который умеет отображать изображение QPixmap, а также выводить текст в нужном месте. На нашем экране-заставке мы отобразим Progress Bar и текстовое сообщение с информацией о готовности приложения к работе (в процентах), а также логотип, копирайт и название программы (для целостности).

Заготовку экрана-заставки нарисуем в любом графическом редакторе:

splash

Мы выделили место под Progress Bar, который будем заполнять сами в зависимости от степени готовности с помощью QPainter. Заметим, что для этой цели можно использовать и стандартный вид QProgressBar, как мы делали это в статье QProgressBar в таблице QTableView.

Приложение состоит из единственного файла main.cpp:

#include <QApplication>
#include <QLabel>
#include <QSplashScreen>
#include <QPainter>
#include <QTime>

static const int LOAD_TIME_MSEC = 5 * 1000;

static const int PROGRESS_X_PX = 272;
static const int PROGRESS_Y_PX = 333;
static const int PROGRESS_WIDTH_PX = 310;
static const int PROGRESS_HEIGHT_PX = 28;

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

    QPixmap pix( ":/images/splash.png" );
    QSplashScreen splashScreen( pix );
    splashScreen.show();
    a.processEvents();

    QTime time;
    time.start();
    while( time.elapsed() < LOAD_TIME_MSEC ) {
        const int progress = static_cast< double >( time.elapsed() ) / LOAD_TIME_MSEC * 100.0;
        splashScreen.showMessage(
            QObject::trUtf8( "Загружено: %1%" ).arg( progress ),
            Qt::AlignBottom | Qt::AlignRight
        );

        QPainter painter;
        painter.begin( &pix );

        painter.fillRect(
            PROGRESS_X_PX,
            PROGRESS_Y_PX,
            progress / 100.0 * PROGRESS_WIDTH_PX,
            PROGRESS_HEIGHT_PX, Qt::gray
        );

        painter.end();

        splashScreen.setPixmap( pix );
        a.processEvents();
    }

    QLabel w;
    w.resize( 200, 200 );
    w.setText( QObject::trUtf8( "Приложение запущено!" ) );
    w.setAlignment( Qt::AlignHCenter | Qt::AlignVCenter );
    w.show();

    splashScreen.finish( &w );

    return a.exec();
}

Для симулирования долгой загрузки мы используем цикл, который проверяет прошедшее время. При этом мы задаем время загрузки LOAD_TIME_MSEC, равным пяти секундам. В реальном приложении в этом месте мы могли бы провести инициализацию: установить сетевые соединения, проверить аппаратуру, загрузить плагины и т.д.

Обратите внимание, что QSplashScreen отображается еще до того, как приложение запускает цикл обработки сообщений a.exec(), поэтому мы не можем использовать систему событий или сигналов-слотов. По этой же причине имеет смысл периодически вызывать a.processEvents() вручную, иначе при некоторых конфигурациях QSplashScreen может не отображаться.

Чтобы QSplashScreen исчез, когда приложение запустится (появится главное окно) не забудьте сделать привязку splashScreen.finish( &w ).

Исходники

 Скачать пример использования QSplashScreen в Qt-приложении

Похожие публикации