Таймеры в 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();
}
Аналогично можно реализовать любую функцию для выполнения отложенных действий. Например, можно создать исчезающую через некоторое время подсказку или организовать "спящий режим" для приложения в случае долгого отсутствия действий со стороны пользователя.