QTimer. Создание таймера и обработка его событий с примером программы.

Здравствуйте.

При написании многих программ часто возникает необходимость следить за временем и периодично выполнять какие-нибудь действия. Для этого используют таймеры. При использовании кроссплатформенного фреймворка Qt используют QTimer.

В этой заметке я расскажу о классе QTimer, о создании таймера и об обработке его событий, о статическом методе singleShot() класса QTimer. На примере покажу, как создать программу, которая показывает текущее время в течение 5-ти секунд, а после закрывается. Таймер в ней нужен для обновления текущего времени на экране каждую секунду. Метод singleShot() понадобится для закрытия программы через 5 секунд.

О классе QTimer

Класс унаследован от QObject, а значит умеет работать с сигналами и слотами. Предоставляет регулярные таймеры, которые по истечении заданного промежутка времени посылают сигнал timeout(). При этом класс имеет статический метод singleShot(), он посылает сигнал через заданный промежуток времени лишь один раз. События таймера будут доставлять только тогда, когда работает цикл обработки событий.

Для использования нужно подключить #include <QTimer>

Включает в себя public-функции:

  • int interval() — возвращает числовое(int) значение установленного интервала таймера в миллисекундах
  • int remainingTime() — возвращает оставшееся время в миллисекундах
  • bool isActive() — возвращает логическое(bool) значение true, если таймер запущен
  • bool isSingleShot() — возвращает true, если таймер включен для срабатывания только один раз
  • void setInterval(int msec) — возволяет установить интервал таймера, где msec — время в миллисекундах
  • void setSingleShot(bool singleShot)
  • void setTimerType(Qt::TimerType atype) — устанавливает тип таймера
  • int timerId() — возвращает id таймера
  • Qt::TimerType timerType() — возвращает тип таймера

Включает в себя слоты start() и stop(), которые запускают и останавливают таймер соответственно. У слота start() есть одна пеперегрузка — start(int msec), которая через msec миллисекунд запускает таймер, если таймер не запущен, в противном случае таймер останавливается и запускается снова.

Имеет сигнал timeout(), который посылается во время срабатывания таймера.

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

Рассмотрим на примере использование таймера. Создадим программу, о которой говорилось выше. Она будет показывать текущее время, а по истечении 5-ти секунд закроется. В ней применим регулярное срабатывание таймера, оно будет обновлять текущее время на экране каждую секунду. Также применим статическую функцию singleShot() для единичного срабатывания, которое пошлет сигнал для закрытия программы.

Создадим проект в Qt Creator, выберем шаблон проекта «Приложение Qt Widgets» или «Application Qt Widgets».

Приложение Qt Widgets

Приложение Qt Widgets

Далее дадим ей любое название, я же назвал «Timer». Остальные параметры по умолчанию.

В дереве проекта переходим в директорию «Формы» | «Forms» и открываем mainwindow.ui. Откроется редактор интерфейсов. В нем нам нужно положить объект Label на форму.

При желании его можно оформить, что я собственно и сделал.

Label на форме

Label на форме

Как видно, я растянул его и увеличил шрифт. Значение «00:00:00» вставил, чтобы было видно размер шрифта.

Далее переходим в «Редактор»|»Edit» -> «Заголовочные»|»Headers»->mainwindow.h.

Подключаем два заголовочных файла <QTime> и <QTimer>. Класс QTime содержит метод currentTime(), который возвращает текущее время, оно пригодится нам в программе.

В этом же файле в классе MainWindow объявим указатель закрытого типа(private) на объект класса QTimer

В ней будет храниться указатель на наш таймер.

Объявим закрытый слот updateTime()

Он будет обновлять время на экране.

Весь листинг файла mainwindow.h

Теперь перейдем в файл mainwindow.cpp («Исходники»|»Source» -> mainwindow.cpp)

В этом файле определим слот updateTime() класса MainWindow

Слот изменяет значение поля text объекта label в нашей форме, помещает в нее значение текущего времени. Статический метод QTime::currentTime() возвращает текущее время, методом toString() мы его преобразовываем в строку, т.к. метод setText(QString arg) принимает на вход только QString. Будем посылать сигнал в этот слот каждую секунду, чтобы обновлялось текущее время на экране.

Далее в конструкторе класса MainWindow создадим новый объект таймера QTimer и передадим его адрес нашей переменной tmr

Зададим интервал таймера в 1 секунду (1 секунда = 1000 миллисекунд)

Соединим сигнал timeout() таймера tmr со слотом updateTime() объекта класса MainWindow

Теперь таймер будет посылать сигнал в наш слот.

Далее сразу же запустим таймер

Метод start() может вызываться с параметром типа int, он задает интервал таймера. Например:

tmr->start(1000); 

Таким образом таймер после запуска будет посылать сигнал с интервалом 1000 мс (каждую секунду).

Листинг файла mainwindow.cpp

В итоге наша программа отображает время и каждую секунду обновляет его. Далее нам нужно «научить» программу закрываться через 5 секунд, для этого переходим к редактированию файла main.cpp («Исходники»|»Sources» -> main.cpp)

В нем тайкже подключим заголовочный файл QTimer

Далее после кода, в котором создается обект окна, вызываем статический метод singleShot() класса QTimer.

Первый параметр метода singleShot() задает значение в миллисекундах, по истечении которых будет послан сигнал.

Второй параметр принимает на вход адрес объекта.

В третьем параметре указывается слот входного объекта.

Листинг файла main.cpp

С редактированием кода всё, осталось запустить нашу программу.

После сборки и запуска появляется такое окно

Окно программы

Окно программы

Время обновляется каждую секунду. После пяти секунд программа закрывается.

Итак, мы узнали о классе QTimer, научились создавать новые таймеры и применили эти знания на практике.

Существуют еще один класс QBasicTimer, который обеспечивает события таймера для объектов, но в данной статье не рассмотрен.

QTimer. Создание таймера и обработка его событий с примером программы.: 7 комментариев

  1. Владимир

    Спасибо! Повторил пример, всё заработало!
    Сейчас хочу модифицировать, чтобы по таймеру увеличивался размер окна

  2. Алексей

    А какой смысл в delete tmr; ?
    В данном случае же освобождение памяти берет на себя Qt.

    1. Tima

      Тоже не вижу смысла в этом, но по правилам хорошего тона вроде бы нужно

  3. Lemiff

    Хороший пример использования QTimer, в своё время до меня долго доходило, т.к. не было нормальных примеров.

  4. Роман

    Пример некорректный. После вызова tmr->start(0); этот нуль попадает в значение таймера и вызовы следуют каждую миллисекунду.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *