Виджеты состояния процесса
Содержание
Пример
Диалог подгружения
Иерархия наследования
Object
+--- Widget
+--- Progress
+--- ProgressBar
Виджеты состояния процесса используются для контроля протекания процесса. Они
довольно удобны, как и будет показано кодом ниже. Но сначала создадим
прогрессбар. Есть два пути создания диалога состояния, один без агрументов,
другой с аргументром выравнивания в соовтетствии с поведением окружения. Еси
используется прежний прогрессбар, то выравнивание будет выстроено в
соответствии с указанным ранее:
$progress = new Gtk::ProgressBar();
$progress = new Gtk::ProgressBar( $adjustment );
Второй метод имеет большие преимущества, так как в нем можно переопределить
или определить заново динамические размеры самого линейки состояния и другие
его параметры:
$progress-> set_adjustment ($adjustment);
Теперь, после создания полосы прокрутки, прогрессбар можно использовать:
$progress->update( $percentage );
Аргумент функции показывает предел заполнения полосы состояния от 0 до 100%
Соответственно функция должна принимать значения от 0.0 до 1.0. Полоса
состояния может быть ориентирована при помощи функции
$progress->set_orientation( $orientation );
где аргумент $orientation, принимает следующие значения:
'left_to_right'
'right_to_left'
'bottom_to_top'
'top_to_bottom'
Вид увеличения полоски состояния может быть определен функцией
$progress->set_bar_style( $style );
в которой аргумент $style может приниметь два значения 'continuous' или
'discrete'. 'continuous' подразумевает непрерывное изменение полоски
состояния, 'discrete' - дискретное. Функцией
$progress->set_discrete_blocks( $blocks );
можно задать число дискрентых блоков виджета состояния. Функция
$progress->set_activity_mode( $activity_mode );
позволяет изменять поведение прогрессбара в том случае, когда идет
уменьшение результата какого-либо процесса. Размер шага актовного индикатора
и число блоков в случае дискретного увеличения может быть установлено при
помощи следующих функций:
$progress->set_activity_step( $step );
$progress->set_activity_blocks( $blocks );
Иногда бывает необходимо показать значения, определяющие продвижение
процесса к конечной цели. Полоса состояния позволяет это сделать в пределах
прогрессбара при помощи функции:
$progress->set_format_string( $format );
где аргумент $format подобен printf и может быть представлен как:
- %p - проценты
- %v - значение
- %l - нижний предел
- %u - верхний предел
показ текста определяется функцией с булевым аргументом:
$progress->set_show_text( $show_text );
Положение текста на прогрессбаре может быть фиксировано при помощи функции:
$progress->set_text_alignment( $x_align, $y_align );
в которой аргументы $x_align и $y_align принимают значения между 0.0 и 1.0
Состояние прогрессбара может быть определено при помощи текущего или
вновь определяемого выравнивания при помощи двух нижепреведенных функций,
возвращающих форматированную строку, которая может быть показана на
прогрессбаре:
$progress-> get_current_text ();
$progress-> get_text_from_value ($value);
тоже самое можно сделать при помощи другой функции:
$progress->configure( $value, $min, $max );
Эта функция обеспечивает довольно простой интерфейс для установления
значений диапазона и значения прогрессбара. Оставшиеся функции используются
для установления значения переменной, отвечающей за уровень прогрессбара в
различных типах и форматах:
$progress->set_percentage( $percentage );
$progress->set_value( $value );
$progress->get_value();
$progress->get_current_percentage();
$progress->get_percentage_from_value( $adjustment );
Здесь проследняя функция использует текущее выравнивание для запроса
текущего значения переменной, отвечающей за состояние выполнения какого-либо
процесса.
Индикаторы состояния процесса используются с таймаутами или другими
подобными функциями с тем, чтобы создать иллюзию мультзадачности(??). Все
они используют функцию update();
Пример индикатора состояния
Нижеследующий пример показывает прогрессбар, изменяющийся при помощи
таймаутов, так же пример показывает, как можно переустановить прогрессбар:
#!/usr/bin/perl -w
use Gtk;
use strict;
set_locale Gtk;
init Gtk;
my $false = 0;
my $true = 1;
my ($window, $pbar, $timer, $align, $separator, $table, $adj, $button, $check1, $check2, $vbox);
# Создаем окно
$window = new Gtk::Window( "toplevel" );
$window->set_policy( $false, $false, $true );
$window->signal_connect( "destroy", sub { Gtk->exit( 0 ); } );
$window->set_title( "Progress Bar" );
$window->border_width( 0 );
$vbox = new Gtk::VBox( $false, 5 );
$vbox->border_width( 10 );
$window->add( $vbox );
$vbox->show();
# Создаем центрированый объект
$align = new Gtk::Alignment( 0.5, 0.5, 0, 0 );
$vbox->pack_start( $align, $false, $false, 5 );
$align->show();
# Создаем выровненный объект, содержащий уровень прогрессбара(???)
$adj = new Gtk::Adjustment( 0, 1, 150, 0, 0, 0 );
# создаем GtkProgressBar, использующий выравнивание
$pbar = new_with_adjustment Gtk::ProgressBar( $adj );
# Устанавливаем формат строки, который может быть показан на индикаторе состояния
# %p - проценты
# %v - значение
# %l - нижний предел
# %u - верхний предел
$pbar->set_format_string( "%v from [%l-%u] (=%p%%)" );
$align->add( $pbar );
$pbar->show();
# Добавляем таймер, который будет запрашивать значение переменной прогрессбара
$timer = Gtk->timeout_add( 100, \&progress_timeout );
$separator = new Gtk::HSeparator();
$vbox->pack_start( $separator, $false, $false, 0 );
$separator->show();
# ряды и колонки, похожести(homogeneous)
$table = new Gtk::Table( 2, 3, $false );
$vbox->pack_start( $table, $false, $true, 0 );
$table->show();
# Add a check button to select displaying of the trough text
# Добавляем кнопку типа select для выбора моды показа или скрытия текста на
# индикаторе состояния процесса
$check1 = new Gtk::CheckButton( "Show text" );
$table->attach( $check1, 0, 1, 0, 1, [ 'expand', 'fill' ],
['expand', 'fill' ], 5, 5 );
$check1->signal_connect( "clicked", sub {
$pbar->set_show_text( $check1->active ); } );
$check1->show();
# Add a check button to toggle activity mode
# Добавляем чекбокс, ответственный за активирование моды
$check2 = new Gtk::CheckButton( "Activity mode" );
$table->attach( $check2, 0, 1, 1, 2, [ 'expand', 'fill' ],
[ 'expand', 'fill' ], 5, 5 );
$check2->signal_connect( "clicked", sub {
$pbar->set_activity_mode( $check2->active ); }
);
$check2->show();
$separator = new Gtk::VSeparator();
$table->attach( $separator, 1, 2, 0, 2, [ 'expand', 'fill' ],
[ 'expand', 'fill' ], 5, 5 );
$separator->show();
# Добавляем радиокнопку, ответственную за непрерывное изменение индикатора
$button = new Gtk::RadioButton( "Continuous" );
$table->attach( $button, 2, 3, 0, 1, [ 'expand', 'fill' ],
[ 'expand', 'fill' ], 5, 5 );
$button->signal_connect( "clicked", sub {
$pbar->set_bar_style( 'continuous' ); } );
$button->show();
# Добавляем радиокнопку, ответственную за дискретное изменение индикатора
$button = new Gtk::RadioButton( "Discrete", $button );
$table->attach( $button, 2, 3, 1, 2, [ 'expand', 'fill' ],
[ 'expand', 'fill' ], 5, 5 );
$button->signal_connect( "clicked", sub {
$pbar->set_bar_style( 'discrete' ); } );
$button->show();
$separator = new Gtk::HSeparator();
$vbox->pack_start( $separator, $false, $false, 0 );
$separator->show();
# Кнопка выхода из программы
$button = new Gtk::Button( "Close" );
$button->signal_connect( "clicked", sub { Gtk->exit( 0 ); } );
$vbox->pack_start( $button, $false, $false, 0 );
# Устанавливаем кнопку выхода по дефолту
$button->can_default( $true );
# захват события и постановка ему в соответствие по дефолту,
# например нажатие кнопки "Enter" завершит программу.
$button->grab_default();
$button->show();
$window->show();
main Gtk;
exit( 0 );
### подпрограммы
# таймер, запрашивающий изменение прогрессбара.
sub progress_timeout
{
my ( $widget ) = @_;
my $new_val;
my $adj;
# Вычисление значения индикатора используюя значение переменной
# диапазона, определенной как выравненный объект(adjustment object)
$new_val = $pbar->get_value() + 1;
$adj = $pbar->adjustment;
$new_val = $adj->lower if ( $new_val > $adj->upper );
# Установка нового значения
$pbar->set_value( $new_val );
return ( $true );
}
Пример диалога подгружения html-страницы
#!/usr/bin/perl -w
use Gtk;
use strict;
set_locale Gtk;
init Gtk;
my $true = 1;
my $false = 0;
my ($command, $site, $dir, $file, $value, $signal, $window, $button, $vbox, $label, $adj, $pbar);
die "Этой программе необходим wget\n" if ( `which wget` =~ /^\s*$/ );
# Создаем окно
$window = new Gtk::Window( 'toplevel' );
$signal = $window->signal_connect( 'delete_event', sub { Gtk->exit( 0 ); });
$window->border_width( 15 );
$vbox = new Gtk::VBox( $false, 0 );
$window->add( $vbox );
# Ярлык, информирующий пользователя о том, на что он идет
$label = new Gtk::Label( "Downloading Gtk-Perl Tutorial" );
$vbox->pack_start( $label, $false, $false, 10 );
$label->show();
# Определение прогрессбара
$adj = new Gtk::Adjustment( 0, 1, 100, 0, 0, 0 );
$pbar = new_with_adjustment Gtk::ProgressBar( $adj );
$vbox->pack_start( $pbar, $false, $false, 10 );
$pbar->set_format_string( "%p%%" );
$pbar->set_show_text( 1 );
$pbar->set_value( 0 );
$pbar->show();
$vbox->show();
# Runs the main loop as long as events are pending
# Запуск основной части программы(???)
Gtk->main_iteration while ( Gtk->events_pending );
$window->show();
# Установки wget
$command = "wget --dot-style=micro";
$site = "http://personal.riverusers.com";
$dir = "/~swilhelm/download/";
$file = "gtkperl-tutorial.tar.gz";
# Открытие временного сокета для перехвата STDOUT wget
open TMP, "$command $site$dir$file 2>&1 |";
while ( $value = )
{
$value =~ s/^.*\[//g;
$value =~ s/ //g;
$value =~ s/\%\]//g;
chomp $value;
$pbar->set_value( ++$value ) if ( $value =~ /^[0-9]+$/ );
# Run the main loop as long as events are pending
# Запуск основной части программы(???)
Gtk->main_iteration while ( Gtk->events_pending );
}
close TMP;
# завершение загрузки, удаление прогрессбара и информирование пользователя
$vbox->remove( $pbar );
$label->set_text( "Download Complete" );
# Create the close button
$button = new Gtk::Button( "Close" );
$button->signal_connect( 'clicked', sub { Gtk->exit( 0 ); } );
$vbox->pack_start( $button, $false, $false, 0 );
$button->show();
main Gtk;
exit( 0 );