Let's talk a bit about using the QTimer class in Qt. This is a small light topic after a series of lengthy articles on QSqlTabelModel and its consequences. And then already at the very gray matter boils.
We may need timers to poll devices over a LAN via the TCP / IP stack at regular intervals, or to check data hourly or active connections to the server. For anything !? And here QTimer comes to our rescue, which We will consider using the example of every second output of time in QLabel.
The program code was written in QtCreator 3.3.1 based on Qt 5.4.1.
Project structure for QTimer
We use a minimum of files in our project:
- QDataMapperWidget.pro - profile;
- mainwindow.h - header file of the main application window;
- mainwindow.cpp - window source code;
- main.cpp - the main source file from which the application starts;
- mainwindow.ui - form of the main application window;
- And we will draw the shape in the QtCreator Designer. However, there is nothing to draw. Throw the QLabel in the middle and you're done.
mainwindow.h
All we need to be happy in this project is a slot that will react to the triggering of a QTimer, and the object of this class itself.
#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
And now a few lines to start the timer. In my opinion, there are more comments than code. Usually they write this way on Assembler - 20% of the code and 80% of the comments.
#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")); }
Outcome
As a result, at startup, we will find out how the time in the application window changes every second.
Добрый день! Появилась проблемка. Есть клиент-серверное приложение. Нужно послать с сервера к клиентам сообщение через определенные промежутки времени. Реализовал это таким образом, что если у нас в 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 написано - это ошибка в статье.