"Нечего на зеркало пенять, если ...интерфейс кривой..."
..пользовательская мудрость..

Создание графических интерфейсов на Perl+Tk.
Автор: (C) 2003, Игорь Яровинский


Вступление.

С появлением языка программирования Perl изменилась жизнь многих программистов, ведь этот язык очень прост в изучении и написании программ. Perl позволяет создавать эффективные инструменты как для обычного пользователя, так и для системного администратора.

Но есть одна проблема: "простые смертные" (читай пользователи), в основном, активно используют мышку и ненавидят консоль, а запоминание параметров команд приводит их в состояние ступора.

Так что же делать Вам, программисту на Perl, чтобы привлечь к своей программе внимание? Да, вопрос не из легких, но и на него есть ответ: создавайте графические интерфейсы для своих программ!

Из этой статьи Вы узнаете, как создавать графические интерфейсы на языке Perl с использованием модулей Tk с CPAN.

Все, о чем будет рассказываться в этой статье проверялось на RedHat 8.0, Xfree86 4.2.0, KDE 3.03, Perl 5.8.0, Tk-800.024. Но я уверен, что если версии Ваших программ не совпадают с моими, то у Вас не возникнет никаких проблем. [Поправка -- не должно возникнуть никаких проблем. И тут, самое главное -- не забыть ещё и сплюнуть. Тьфу-тьфу... :-) Прим.ред.]

Установка модулей.

Об установке Perl и графических менеджеров я рассказывать не буду -- об этом уже написано немало статей. Давайте лучше обратим внимание на установку Tk-модулей для Perl. Если Вы используете rpm-based дистрибутив Linux, то проверьте, не поставляется ли библиотека модулей Tk с Вашим дистрибутивом. Как правило, если в его состав входят Perl и Tk, то обязательно должен присутствовать пакет perl-Tk. Тоже самое можно сказать и о Debian-based дистрибутивах или Slackware. Но так как всё описанное в этой статье проверялось на RedHat, то и речь будет идти об rpm-пакетах.

Если в Вашем дистрибутиве нет rpm-пакета с библиотекой Tk, то загрузите соответствующий тарбол с CPAN (ftp.CPAN.org). На сегодняшний день последней версией является Tk-800.024.

Итак, займемся установкой:
Если у Вас есть rpm-пакет с perl-Tk, то установите его:

        # rpm -ivh perl-Tk-номер_версии-сборка.архитектура.rpm

Если Вы являетесь обладателем дистрибутива компании ALT Linux, то для установки perl-Tk можете воспользоваться пакетом APT (Advanced Packaging Tool):

        # apt-get install perl-Tk

Примечание. Кстати, уже существует вариант APT для RedHat. О его установке Вы можете прочитать здесь. APT -- один из наиболее удобных инструментов для установки пакетов, разработанный в недрах проекта Debian GNU/Linux.

Если Вы используете архив с CPAN, то распакуйте его:

        # tar xzvf Tk-номер_версии.tar.gz

зайдите в появившийся каталог Tk-номер_версии

        # cd Tk-номер_версии

выполните следующие команды:

        # perl Makefile.PL
        # make
        # make  install

Вот, собственно, и вся установка. Если возникли какие-то проблемы, то прочитайте файл INSTALL, который находится в этом же каталоге.

Знакомство с возможностями Perl+Tk.

Давайте для начала посмотрим, что же все-таки можно делать на Perl с использованием Tk. Для этого запустите свой любимый оконный менеджер (например, KDE) и выполните команду:

        # widget

Походите по пунктам меню, ссылкам... Нравится? Точно такие же по красоте приложения сможете делать и Вы!

Первая программа на Perl+Tk.

Любая Perl-программа, использующая Tk должна содержать строку

        use Tk;

которая подключает модуль для создания графического интерфейса. Для корректной работы программы и возможности отслеживания ошибок, желательно, чтобы Perl запускался с ключом -w, и в программе была строка:

        use strict;

А вот пример самой простой программы, которая выдает окно с сообщением "Hello, World!".

   #!/usr/bin/perl -w

      use strict;
      use Tk;

      my $main = MainWindow->new;
      $main->Label(-text => 'Hello, world!')->pack;
      $main->Button(-text => 'Quit',
                    -command => [$main => 'destroy']
                   )->pack;
     MainLoop;

Тут все понятно, но давайте все-таки разберемся как работают программа и модули Tk.
Все объекты (окна, кнопки, меню, надписи, текстовые поля ...), созданные с использованием Tk, имеют иерархическую структуру. Это значит, что один объект может содержать другой объект или несколько объектов. Первое окно (первый объект) создается с помощью

        MainWindow->new

а возвращаемый дескриптор нового окна сохраняется в переменной $main. Далее, вызывая

        $main->Label(-text => 'Hello, world!')

мы создаем новый объект, и используя его конструктор, заносим в него строку 'Hello, world!'. Вызовом

        $main->Button(-text => 'Quit',  -command => [$main => 'destroy'])

создается кнопка с надписью 'Quit', а при ее нажатии происходит событие [$main => 'destroy'], то есть закрытие окна. Это же событие можно описать и так:

        -command => sub{exit}.

После создания любого дочернего объекта, необходимо его разместить на родительском и отобразить. Этим занимается метод pack. О параметрах, с которыми вызывается этот метод можно узнать из документации.

Чтобы уничтожить любой объект, нужно вызвать метод destroy. Например, создав объект

        $object=$main->Label(-text =>'HELLO')->pack;

удалить его можно будет, вызвав

        $object->destroy;

Создание более полезного приложения.

Теперь давайте займемся созданием более полезного приложения. Например, консольная программа 'finger user_name' дает возможность узнать информацию о user_name. Точно такую же программу, но с графическим интерфейсом, мы сейчас создадим. Для этого будет использоваться файл /etc/passwd. В этом файле записи для каждого пользователя разделены двоеточием. Для получения нужной информации, мы будем построчно читать этот файл, разбивать строку на поля функцией split и искать пользователя с заданным именем. В этом примере для создания диалогового окна будет использован новый модуль, Tk::DialogBox

Итак, код всей программы выглядит так:

#!/usr/bin/perl -w
use Tk;
use Tk::DialogBox;
use strict;

my($main,$Edit);

$main=MainWindow->new(-title => 'FINGER'); #Создание окна с заголовком 'FINGER'

$main->Label(-text => 'Finger application')->pack;    #Создание надписей 'Finger application'
$main->Label(-text => 'Enter user name')->pack;       #и 'Enter user name',
$Edit=$main->Entry(-width => 20)->pack;               #поле для ввода, шириной в 20 символов,
$main->Button(-text => 'Show Info',                   #и кнопка с надписью 'Show Info',
          -command => \&ShowInfo)->pack(-side => 'left'); #при нажатии которой
                                                          #вызывается подпрограмма ShowInfo.
$main->Button(-text    => 'Exit',                #Создание кнопки для
          -command => [$main => 'destroy']       #закрытия окна
         )->pack;

MainLoop;

#Подпрограмма ShowInfo производит поиск имени пользователя, заданного в текстовом поле,
#используя файл /etc/passwd, и в случае удачи выводит окно с найденной информацией о пользователе

sub ShowInfo
    {
     my($InfoWindow, $request, $found, $User, $GECOS, $HomeDir, $Shell, $RealName, $HomePhone);

     #Создание диалогового окна с кнопкой OK. Это окно будет отображено только
     #после вызова метода Show.
     $InfoWindow=$main->DialogBox(-title   => 'User Information',
                                  -buttons => ["OK"]);
     open (FL,"/etc/passwd");
     $request=$Edit->get;         #Получить имя пользователя из поля для ввода текста
     while (<FL>)
     {
      chomp();
      ($User,$GECOS,$HomeDir,$Shell)=(split /:/)[0,4,5,6]; #Разбор записи о пользователе
      ($RealName,$HomePhone)=(split(/,/,$GECOS))[0,3];     #Разбор поля GECOS
      if ($User eq $request)
        {
     $found=1;
     last;
    }
      }
       if($found==1)
     #Если данные о пользователе были найдены, то окно InfoWindow заполняется соответствующей
     #информацией. Если же данные найдены не были (блок else), то в окно будет помещено
     #сообщение об отсутствии в файле /etc/passwd записи о пользователе.
       {
        $InfoWindow->add("Label", -text => "LinuxUser: $User")->pack;
        $InfoWindow->add("Label", -text => "User name: $RealName")->pack;
        $InfoWindow->add("Label", -text => "Home phone: $HomePhone")->pack;
        $InfoWindow->add("Label", -text => "Home directory: $HomeDir")->pack;
        $InfoWindow->add("Label", -text => "User shell: $Shell")->pack;
       }else{
         $InfoWindow->add("Label", -text => "  There is no such user ")->pack;
         $InfoWindow->add("Label", -text => "in your /etc/passwd file")->pack;
    }
        $InfoWindow->Show();           #Показать окно InfoWindow
    $InfoWindow->destroy;              #После нажатия кнопки OK, окно будет закрыто
    close(FL);
   }

Хоть эта программа примитивна и не предусматривает различные "критические ситуации" (например, отсутствие файла /etc/passwd), но она в достаточной степени демонстрирует те возможности, что появляются у программиста при использовании тандема Perl+Tk.

Дополнительная информацию о Perl+Tk:

[К сожалению, издательство O'Reilly не предоставляет online-версии этих книг. Прим.ред.]

Copyright (c) 2003, Igor Yarovinsky.

Hosted by uCoz