"Нечего на зеркало пенять, если ...интерфейс кривой..."
..пользовательская мудрость..
Создание графических интерфейсов на 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. Для этого запустите свой любимый оконный менеджер (например, KDE) и выполните команду:
# widget
Походите по пунктам меню, ссылкам... Нравится? Точно такие же по красоте приложения сможете делать и Вы!
Любая 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.
Copyright (c) 2003, Igor Yarovinsky.