Виджеты состояния процесса Содержание Пример Диалог подгружения Иерархия наследования 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 и может быть представлен как:
  1. %p - проценты
  2. %v - значение
  3. %l - нижний предел
  4. %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 );