БлогNot. QT: обрабатываем событие таймера

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
окно виджета RunningString

 Скачать папку с этим проектом QT5 в архиве .zip (3 Кб)

03.03.2017, 15:30 [4884 просмотра]


теги: программирование c++ время qt

К этой статье пока нет комментариев, Ваш будет первым