11 июня 2009 г.

Секундомер

Сегодня мы рассмотрим процесс создания секундомера. Это будет программа с двумя кнопками. При нажатии на первую - секундомер запускается, на вторую - останавливается. Время будет выводиться в GtkLabel с точностью до одной десятой секунды.



Я надеюсь, что у вас не возникнет сложностей с созданием элементов управления, поэтому останавливаться на этом не буду. Скажу лишь, что по умолчанию GtkLabel должен иметь значение '0:0', а кнопка 'Остановить таймер' должна быть неактивной.
$button_stop->set_sensitive(FALSE);


function timer_start()
{
global $label, $button_stop, $button_start, $timeout_id, $clear;
 
$button_stop->set_sensitive(TRUE);
$button_start->set_sensitive(FALSE);
 
if ($clear)
{
$text = '0:0';
$clear = FALSE;
}
else
$text = $label->get_text();
$explode = explode(':', $text);
$s = $explode[0];
$ms = $explode[1];
$ms++;
if ($ms == 10)
{
$s++;
$ms = 0;
}
$label->set_text($s.':'.$ms);
$timeout_id = Gtk::timeout_add(100, 'timer_start');
}

При нажатии на 'Запустить таймер' будем вызывать функцию timer_start. В ней мы сначала меняем активность кнопок, затем проверяем значение глобальной переменной $clear. Если оно равно TRUE, то сбрасываем значение счётчика и начинаем отсчёт заново. Далее получаем значение счётчика, увеличиваем количество миллисекунд (переменная $ms) и если оно достигло десяти, то увеличиваем количество секунд (переменная $s), и записываем результат в GtkLabel. Далее идёт вызов функции, без которой реализация секундомера была бы невозможна.
$timeout_id = Gtk::timeout_add(100, 'timer_start');

Она каждые 100 миллисекунд (напомню, что в одной секунде - 1000мс) вызывает функцию timer_start().

function timer_stop()
{
global $timeout_id, $button_stop, $button_start, $clear;
 
$button_stop->set_sensitive(FALSE);
$button_start->set_sensitive(TRUE);
Gtk::timeout_remove($timeout_id);
$clear = TRUE;
}

Данная функция вызывается при остановке таймера. Она меняет активность кнопок и останавливает таймер. Также необходимо присвоить переменной $clear значение TRUE для того, чтобы при запуске секундомера счётчик сбросился на нули.

Полный код программы:
<?php
 
$window = new GtkWindow();
$window->set_size_request(400, -1);
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
$vbox = new GtkVBox;
 
$label = new GtkLabel('0:0');
$button_start = new GtkButton('Запустить таймер');
$button_start->set_image(GtkImage::new_from_stock(Gtk::STOCK_OK,
Gtk::ICON_SIZE_BUTTON));
$button_start->connect_simple('clicked', 'timer_start');
$button_stop = new GtkButton('Остановить таймер');
$button_stop->set_image(GtkImage::new_from_stock(Gtk::STOCK_STOP,
Gtk::ICON_SIZE_BUTTON));
$button_stop->set_sensitive(FALSE);
$button_stop->connect_simple('clicked', 'timer_stop');
 
function timer_start()
{
global $label, $button_stop, $button_start, $timeout_id, $clear;
 
$button_stop->set_sensitive(TRUE);
$button_start->set_sensitive(FALSE);
 
if ($clear)
{
$text = '0:0';
$clear = FALSE;
}
else
$text = $label->get_text();
$explode = explode(':', $text);
$s = $explode[0];
$ms = $explode[1];
$ms++;
if ($ms == 10)
{
$s++;
$ms = 0;
}
$label->set_text($s.':'.$ms);
$timeout_id = Gtk::timeout_add(100, 'timer_start');
}
 
function timer_stop()
{
global $timeout_id, $button_stop, $button_start, $clear;
 
$button_stop->set_sensitive(FALSE);
$button_start->set_sensitive(TRUE);
Gtk::timeout_remove($timeout_id);
$clear = TRUE;
}
 
$hbox = new GtkHBox;
$hbox->pack_start($button_start);
$hbox->pack_start($button_stop);
$vbox->pack_start(new GtkLabel);
$vbox->pack_start($label, FALSE, FALSE);
$vbox->pack_start(new GtkLabel);
$vbox->pack_start($hbox, FALSE, FALSE);
$window->add($vbox);
$window->show_all();
Gtk::main();
 
?>

Комментариев нет: