Трохи поговоримо про застосування класу QTimer у Qt. Це невелика легка тема після серії об'ємних статей про QSqlTabelModel і наслідків, що випливають з неї. А то вже у самого сіра речовина закипає.
Таймери нам можуть знадобитися для створення опитування пристроїв по ЛОМ через стек TCP/IP з певною періодичністю або для щогодинної перевірки даних або активних підключень до сервера. Та навіщо завгодно!? І тут нам на допомогу приходить QTimer, який ми розглянемо на прикладі щомиті виведення часу в QLabel.
Програмний код був написаний QtCreator 3.3.1 на основі Qt 5.4.1.
Структура проекту для QTimer
Використовуємо мінімум файлів у нашому проекті:
- QDataMapperWidget.pro - профайл;
- mainwindow.h - заголовний файл основного вікна програми;
- mainwindow.cpp - вихідний код вікна;
- main.cpp - основний вихідний файл, з якого стартує програма;
- mainwindow.ui - форма основного вікна програми;
- А форму намалюємо в Дизайнері QtCreator. Втім, там і малювати нічого. Кинули QLabel у середину і готове.
mainwindow.h
Все, що нам потрібно для щастя в цьому проекті - це слот, який реагуватиме на спрацювання QTimer, та сам об'єкт цього класу.
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QFont> #include <QTimer> #include <QTime> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); /* Будем использовать только один слот */ private slots: void slotTimerAlarm(); private: Ui::MainWindow *ui; /* Да сам объект QTimer */ QTimer *timer; }; #endif // MAINWINDOW_H
mainwindow.cpp
А тепер кілька рядків із запуску таймера. По-моєму, коментарів більше, ніж коду. Зазвичай так на Assembler'і пишуть - 20% коду та 80% коментарів.
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); /* Немножко подшаманим QLabel, чтобы он был больше, * и заметнее в пустующем окне * */ QFont font("Times", 28, QFont::Bold); ui->label->setFont(font); /* При первом запуске приложения поместим текущее время в QLabel * */ ui->label->setText(QTime::currentTime().toString("hh:mm:ss")); /* Инициализируем Таймер и подключим его к слоту, * который будет обрабатывать timeout() таймера * */ timer = new QTimer(); connect(timer, SIGNAL(timeout()), this, SLOT(slotTimerAlarm())); timer->start(1000); // И запустим таймер } MainWindow::~MainWindow() { delete ui; } /* Слот для обработки timeout() таймера * */ void MainWindow::slotTimerAlarm() { /* Ежесекундно обновляем данные по текущему времени * Перезапускать таймер не требуется * */ ui->label->setText(QTime::currentTime().toString("hh:mm:ss")); }
Підсумок
В результаті при запуску виявимо, як кожну секунду у нас змінюється час у вікні програми
Добрый день! Появилась проблемка. Есть клиент-серверное приложение. Нужно послать с сервера к клиентам сообщение через определенные промежутки времени. Реализовал это таким образом, что если у нас в QList лежит больше 1 сокета, то сначало посылается сообщение 1 клиенту, а потом включается таймер, но перед этим записывалось значение i в глобальную переменну(i взято из for). Использовал QTimer::singleshot(2000,this,Slot(slotZ()));. происходит вызов другой функции, где значение сокета берется из списка, по номеру как раз взятого из глобальной переменны, но почему то заместо того чтобы послать на 2 и 3 клиент через 2 сек сообщение, он посылает 2 сообщения на последний клиент.
Спасибо! Учту.
Вижу вы используете
new QTimer();
А кто будет память освобождать?
Почему вы вообще используете указатель QTimer *timer; а не объявите поле QTimer timer;?
Потому что 7 лет назад я был бестолковее, чем сейчас.
QTimer унаследован от QObject и ему передан this, идиома Qt предпологает что при вызове деструктора обьекта класса MyServer, обьект *timer тоже будет освобожден. Поправьте если ошибаюсь!
Да, именно так. Но в коде без this написано - это ошибка в статье.