IT Notes

QTimer: Примеры использования

Таймеры в Qt (и не только) позволяют выполнять некий код по заданным временным интервалам. Для таймеров существует два наиболее очевидных варианта использования. Рассмотрим соответствующие примеры.

Таймер для периодического выполнения действий

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

Создадим виджет, который каждую секунду меняет цвет своего фона. Заголовочный файл timerdemowidget.h:

#ifndef TIMERDEMOWIDGET_H
#define TIMERDEMOWIDGET_H

#include <QWidget>
#include <QTimer>

class TimerDemoWidget : public QWidget {
    Q_OBJECT

public:
    TimerDemoWidget( QWidget* parent = 0 );
    ~TimerDemoWidget();

private slots:
    void setRandomBackgroundColor();

private:
    QTimer m_timer;
};

#endif // TIMERDEMOWIDGET_H

Реализация timerdemowidget.cpp:

#include "timerdemowidget.h"

TimerDemoWidget::TimerDemoWidget( QWidget* parent )
    : QWidget( parent ) {

    connect( &m_timer, SIGNAL( timeout() ), SLOT( setRandomBackgroundColor() ) );
    m_timer.start( 1000 ); // Таймер будет срабатывать каждые 1000 миллисекунд, т.е. каждую секунду
}

TimerDemoWidget::~TimerDemoWidget() {
}

void TimerDemoWidget::setRandomBackgroundColor() {
    QPalette palette( this->palette() );
    int r = qrand() % 256;
    int g = qrand() % 256;
    int b = qrand() % 256;
    palette.setColor( QPalette::Background, QColor( r, g, b ) );
    setPalette( palette );
}

Таймер запускается с помощью QTimer::start(). Остановить таймер можно вызовом QTimer::stop().

Для изменения цвета фона виджета используется объект палитры QPalette. Сам цвет QColor формируется из трех компонент r, g, b, выбранных случайным образом.

Осталось отобразить виджет:

#include <QApplication>
#include "timerdemowidget.h"

int main( int argc, char* argv[] ) {
    QApplication a( argc, argv );
    TimerDemoWidget w;
    w.resize( 100, 100 );
    w.show();

    return a.exec();
}

Похожий прием хорошо подходит для создания простых эффектов и анимации (например, мигающего текста или исчезающих кнопок).

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

Таймер для отложенного выполнения действия

QTimer хорошо подходит и в тех случаях, когда требуется выполнить действие всего один раз, но не сразу, а через некий временной интервал. Для этого предусмотрена функция-член QTimer::singleShot().

В следующем примере приводится код приложения, которое само завершается через 5 секунд после старта:

#include <QCoreApplication>
#include <QTimer>

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

    QTimer::singleShot( 5000, &a, SLOT( quit() ) );

    return a.exec();
}

Аналогично можно реализовать любую функцию для выполнения отложенных действий. Например, можно создать исчезающую через некоторое время подсказку или организовать "спящий режим" для приложения в случае долгого отсутствия действий со стороны пользователя.

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