QT: обрабатываем событие таймера
В стандартных примерах QT 5.X есть красивый виджет Wiggly Example, демонстрирующий обработку события таймера. Сделаем аналогичное приложение без привлечения усложнённых эффектов, связанных с рисованием на канве. Наш виджет будет просто переставлять с шагом по времени буквы некоторой строки и выводить эту строку в текстовую метку QLabel
. Текст строки можно будет ввести в однострочное поле ввода QLineEdit
, а регулировать интервал времени, через который вызывается таймер, с помощью стандартного "бегунка" QSpinBox
.
Создадим виджет RunningString
на основе шаблона QWidget
("лишнюю" сущность ui
потом оттуда уберём), а нужные компоненты разместим программно из конструктора виджета.
Стандартная метка QLabel
не умеет работать с таймером. Логично создать класс TimerLabel
- наследник QLabel
, который это делает. Добавим в проект класс TimerLabel
и опишем в файле TimerLabel.h
соответствующий функционал.
Здесь и далее разобраться в коде помогут комментарии.
Файл timerlabel.h
#ifndef TIMERLABEL_H #define TIMERLABEL_H #include <QLabel> class TimerLabel : public QLabel { Q_OBJECT protected: virtual void timerEvent (QTimerEvent *); //обработчик события таймера int shiftArray; //сдвиг строки от начала int timerId; //метка активности таймера QString timerString; //строка, которую "крутим" public slots: void setTimerString (QString); //метод для установки новой строки в метку void setTimerSpeed (int); //метод для установки интервала повторения таймера public: TimerLabel(QString="",QWidget *parent=0); //конструктор нашей метки }; #endif // TIMERLABEL_H
Файл timerlabel.cpp
#include "timerlabel.h" TimerLabel::TimerLabel(QString string,QWidget *parent) : QLabel(string,parent),shiftArray(0),timerId(0) { //просто вызываем стандартный конструктор метки + //инициализируем новые свойства класса-потомка } void TimerLabel::timerEvent (QTimerEvent *event) { //Пишем здесь код, который должен выполняться периодически int length = timerString.length(); if (++shiftArray > length) shiftArray=0; setText( //наш класс - потомок QLabel, у него есть //методы родителя timerString.right(shiftArray)+ timerString.left(length-shiftArray)); } void TimerLabel::setTimerString (QString string) { //метод для установки строки метки timerString = string; shiftArray = 0; setText (timerString); } void TimerLabel::setTimerSpeed (int speed) { //метод для установки таймера if (timerId) QObject::killTimer (timerId); //так можно остановить существующий таймер timerId = 0; speed = qAbs (speed); if (speed > 10) speed = 1; timerId = QObject::startTimer (1000/speed); //а так - запустить таймер }
Основному виджету останется только подготовить форму и запустить таймер.
Файл widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QtWidgets> #include "timerlabel.h" class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); }; #endif // WIDGET_H
Файл widget.cpp
#include <QGridLayout> #include "widget.h" #include "timerlabel.h" Widget::Widget(QWidget *parent):QWidget(parent) { //Разместим компоненты на форме: QGridLayout *layout = new QGridLayout(this); QLineEdit *lineedit = new QLineEdit (this); QSpinBox *spinbox = new QSpinBox (this); spinbox->setMinimum(1); spinbox->setMaximum(10); QString InitialString("Hello, world!"); TimerLabel *label = new TimerLabel (InitialString,this); layout->addWidget(lineedit,1,1); layout->addWidget(spinbox,1,2); layout->addWidget(label,2,1,1,2,Qt::AlignJustify); //Подключаем слоты приложения: connect(lineedit,SIGNAL(textChanged(QString)), label,SLOT(setTimerString(QString))); connect(spinbox,SIGNAL(valueChanged(int)), label,SLOT(setTimerSpeed(int))); //Выводим строку и запускаем таймер: label->setTimerSpeed(1); lineedit->setText(InitialString); }
Текстовую метку, в которой будет "бежать" строка, выровняем указанием Qt::AlignJustify
, чтобы избежать переносов слов в метке.
Главная программа main.cpp
будет совершенно обычной, она просто запустит экземпляр виджета.
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
Вот какой виджет у нас получился:
окно виджета RunningString
Скачать папку с этим проектом QT5 в архиве .zip (3 Кб)
03.03.2017, 15:30 [5018 просмотров]