Читаем QT 4: программирование GUI на С++ полностью

19 void Ticker::paintEvent(QPaintEvent * /* event */)

20 {

21 QPainter painter(this);

22 int textWidth = fontMetrics.width(text);

23 if (textWidth < 1)

24 return;

25 int х= -offset;

26 while (x < width) {

27 painter.drawText(x, 0, textWidth, height,

28 Qt::AlignLeft | Qt::AlignVCenter, text);

29 x += textWidth;

30 }

31 }

Функция paintEvent отображает текст при помощи функции QPainter::drawText. Она использует функцию fontMetrics для определения размера области, занимаемой текстом по горизонтали, и затем выводит текст столько раз, сколько необходимо для заполнения виджета по всей его ширине, учитывая значение смещения offset.

32 void Ticker::showEvent(QShowEvent * /* event */)

33 {

34 myTimerId = startTimer(30);

35 }

функция showEvent запускает таймер. Вызов QObject::startTimer возвращает число—идентификатор, которое мы можем использовать позже для идентификации таймера. QObject поддерживает несколько независимых таймеров, каждый из которых использует свой временной интервал. После вызова функции startTimer Qt генерирует событие таймера приблизительно через каждые 30 миллисекунд, причем точность зависит от базовой операционной системы.

Мы могли бы функцию startTimer вызвать в конструкторе Ticker, но мы экономим некоторые ресурсы за счет генерации Qt событий таймера только в тех случаях, когда виджет действительно видим.

36 void Ticker::timerEvent(QTimerEvent *event)

37 {

38 if (event->timerId == myTimerId) {

39 ++offset;

40 if (offset >= fontMetrics.width(text))

41 offset= 0;

42 scroll(-1, 0);

43 } else {

44 QWidget::timerEvent(event);

45 }

46 }

Функция timerEvent вызывается системой в соответствующие моменты времени. Она увеличивает смещение offset на 1 для имитации движения по всей области вывода текста. Затем она перемещает содержимое виджета на один пиксель влево при помощи фyнкции QWidget::scroll. Вполне достаточно было бы вызывать функцию update вместо scroll, но вызов функции scroll более эффективен, потому что она просто перемещает существующие на экране пиксели и генерирует событие рисования для открывшейся области виджета (которая в данном случае представляет собой полосу шириной в один пиксель).

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

47 void Ticker::hideEvent(QHideEvent * /* event */)

48 {

49 killTimer(myTimerId);

50 }

Функция hideEvent вызывает QObject::killTimer для остановки таймера.

События таймера являются низкоуровневыми событиями, и если нам необходимо иметь несколько таймеров, это может усложнить отслеживание всех идентификаторов таймеров. В таких ситуациях обычно легче создавать для каждого таймера объект QTimer. QTimer генерирует через заданный временной интервал сигнал timeout. QTimer также обеспечивает удобный интерфейс для однократных таймеров (то есть таймеров, которые срабатывают только один раз).

<p>Установка фильтров событий</p>

Одним из действительно эффективных средств в модели событий Qt является возможность с помощью некоторого экземпляра объекта QObject контролировать события другого экземпляра объекта QObject еще до того, как они дойдут до последнего.

Предположим, что наш виджет CustomerInfoDialog состоит из нескольких редакторов строк QLineEdit и мы хотим использовать клавишу Space (пробел) для передачи фокуса следующему QLineEdit. Такой необычный режим работы может оказаться полезным для разработки, предназначенной для собственных нужд, и когда пользователи имеют навык работы в таком режиме. Простое решение заключается в создании подкласса QLineEdit и переопределении фyнкции keyPressEvent для вызова focusNextChild, и оно выглядит следующим образом:

01 void MyLineEdit::keyPressEvent(QKeyEvent *event)

02 {

03 if (event->key== Qt::Key_Space) {

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже