分类:
2008-05-10 21:54:41
尽管基于 Perl 的 Web 接口存在局限性,但 Perl 仍是最常用的 Web 开发语言之一。在 Shell 脚本、Perl 或其他语言方面有编程经验的 UNIX? 用户可通过使用 Perl/Tk 模块为基于 Perl 的 Web 接口带来新的生机。
Perl 语言经常由 IBM AIX 操作系统管理员和开发人员使用,几乎每个成功的网站和大多数 AIX 系统上都使用了该语言。尽管 Perl 脚本的功能非常强大,但它产生的 Web 接口却缺少图形化前端,用户必须键入信息,而不能使用鼠标,对于客户来说,这一点非常不尽人意。随着 Perl 中 Tk 模块的引入,此问题已得到解决。管理员或开发人员可以利用 Tk 模块快速为其 Perl 脚本带来新的生机,从而满足客户对 X11 产品的需要。
Perl 即“实际提取和报告语言”,是 Larry Wall 于 1987 创建的,作为一种简化其编程工作的手段。从其创建以来,Perl 已经发展成为全球使用的语言,目前是大多数管理员和开发人员的必备工具。
Perl/Tk 模块(也称 pTk 或 ptk)是一个专门用来创建小部件或其他通用图形对象以构成图形用户界面 (GUI) 的 Perl 模块。使用该模块创建的 GUI 改善了程序的外观,可帮助最终用户通过程序及其函数进行导航。使用 Perl/Tk 模块的一个主要优势是最终产生的应用程序可以跨平台运行,这意味着,同一 GUI 应用程序可用于 UNIX?、Linux?、Macintosh、Microsoft? Windows? 或其他任何安装了 Perl 和 Perl/Tk 模块的操作系统。
在您使用 Perl/Tk 模块编写应用程序之前,必须验证是否安装了 Perl 和 Perl/Tk 模块。尽管 Perl 一般会安装在计算机上,Perl/Tk 模块却并非如此。检查是否安装了 Perl 的一种方法是在命令行中输入 perl --version
。如果未安装 Perl,请参考 Perl 网站上的安装指南(请参阅参考资料)。
在找到 Perl 或将其安装到您的计算机上之后,下一步则是确定是否需要安装 Perl/Tk 模块。检查是否安装了模块的一种简单方法是在命令提示符下键入 perl -e "use module"
。若要验证是否安装了 Perl/Tk 模块,请执行以下命令:
perl -e "use Tk" |
Can't locate Tk.pm in @INC (@INC contains: /opt/ActivePerl-5.8/site/lib /opt/ActivePerl-5.8/lib .) at -e line 1. BEGIN failed--compilation aborted at -e line 1. |
请记住,Perl 是区分大小写的:perl –e "use Tk"
和 perl –e "use tk"
是尝试使用两种不同模块(Tk 和 tk)的两种不同语句。
如果未发现该模块,下一步则是下载并安装该模块。您可以用多种方法完成此操作。
如果您使用的是 UNIX 或 Linux,下载和安装 Perl 模块的一种方法是使用 Comprehensive Perl Archive Network (CPAN)。在命令提示符中输入以下命令:
perl –MCPAN –e shell install Bundle::CPAN reload cpan install Tk |
如果您使用的是 Windows,类似的方法是使用 Perl Package Manager (PPM)。在命令提示符中,输入 ppm
以启动 GUI 并下载 Tk 模块。
完成安装后,通过执行 perl –e "use Tk"
重新验证 Perl 是否可找到该模块。
既然计算机上已经安装了 Perl 和 Perl/Tk 模块,现在就可以通过该模块编写您的第一个 GUI 程序了。开始时可以编写一个简单的 Hello World 程序。利用您喜欢的文本编辑器,创建一个名为 helloworld.pl 的文件,然后在文件中输入以下文本:
#!/usr/bin/perl -w # Display Hello World program use Tk; use strict; my $mw = MainWindow->new; $mw->geometry("200x100"); $mw->title("Hello World!!!"); $mw->Label(-text => 'Hello World')->pack(); $mw->Button(-text => "Close", -command =>sub{exit})->pack(); MainLoop; |
执行此脚本将生成 GUI 应用程序,如下面的图 1 所示。
让我们逐行分解一下此脚本:
#!/usr/bin/perl -w |
第一部分 (/usr/bin/perl
) 定义了 Perl 可执行文件在计算机上驻留的位置,指示计算机使用该 Perl 可执行文件的副本执行 helloworld.pl 文件。此命令行的第二部分 (-w
) 是 Perl 中的一个重要工具:它支持在执行脚本时发出警告,通知最终用户可能发现的任何错误。
在执行期间不应评估的注释和文本前面都加上了一个 #
号:
# Display Hello World program |
为了让 Perl 脚本使用 Tk 模块,还必须包含此模块,即 use Tk
。将 use strict
语句添加到 Perl 脚本还有助于发现任何可能的输入或逻辑错误:
use Tk; use strict; |
要创建应用程序的主窗口,请使用 MainWindow
,并将它分配给 $mw
。$mw
充当所有其他小部件的父部件:
my $mw = MainWindow->new; |
将主窗口大小设置为 200 x 100,让该窗口的标题为“Hello World!!!”:
$mw->geometry("200x100"); $mw->title("Hello World!!!"); |
在主窗口内创建一个标签,并使用标题 Hello World。标签创建的末尾是一个附加函数 pack
,它是一个几何管理器。该管理器用于小部件上,用来计算在小部件的父部件上分配的空间;同时还显示该小部件:
$mw->Label(-text => 'Hello World')->pack(); |
该代码行在主窗口中创建一个“Close”按钮。当通过鼠标点击激活或用键盘执行它后,此按钮将退出 Perl 脚本:
$mw->Button(-text => "Close", -command =>sub{exit})->pack(); |
而且,由于此按钮占用主窗口的空间,所以需要使用 pack
函数来计算所占用的空间。
在执行 MainLoop
之前,可以读取、定义和随时执行该脚本中的所有内容。然后,当调用 MainLoop
时,将执行在此之前读取的所有函数和数据,并显示 GUI。
MainLoop; |
本部分将介绍一些小部件。本部分将介绍几个基本小部件,并提供有关每个小部件的示例,其中包括框架、文本、入口、按钮和标签。
小部件 是一种可以执行特定功能的图形对象。Perl/Tk 模块中的任何图形对象都可以视为一个小部件。对于 GUI 应用程序而言,按钮、文本、框架和滚动栏都是小部件。
下面的小部件示例构成了本文稍后将要讨论的小部件的基础。
框架小部件正如其名称所描述的那样:是一个框架或盒子。框架用来对其他小部件进行分组。
请输入下面的脚本:
#!/usr/bin/perl -w use Tk; use strict; my $mw = MainWindow->new; $mw->geometry("200x100"); $mw->title("Frame Test"); $mw->Frame(-background => 'red')->pack(-ipadx => 50, -side => "left", -fill => "y"); $mw->Frame(-background => 'blue')->pack(-ipadx => 50, -side => "right", -fill => "y"); MainLoop; |
执行此脚本时,会生成一个 GUI 应用程序,如图 2 所示。
下面我们分析一下该脚本:
#!/usr/bin/perl -w use Tk; use strict; my $mw = MainWindow->new; $mw->geometry("200x100"); $mw->title("Frame Test"); … … MainLoop; |
本部分在前面的示例中已讨论过,因此,现在我们看一个新语句。
创建一个使用主窗口作为父窗口的框架,并将背景颜色设置为红色。与前面的 pack
方法示例不同,这里包括了几个选项:
$mw->Frame(-background => 'red')->pack(-ipadx => 50, -side => "left", -fill => "y"); |
第一个参数 ipadx
将框架的宽度增加了 100 (50 x 2)。第二个参数 side
将该框架的几何位置调整到了其父框架 ($mw
) 的左侧。第三个参数按照 y
轴方向(垂直)在该框架内分配空间。
此框架类似于前面的框架,但背景是蓝色的,位置在主窗口的右侧:
$mw->Frame(-background => 'blue')->pack(-ipadx => 50, -side => "right", -fill => "y"); |
文本小部件创建一个可编辑的文本工作区。请输入下面的脚本:
#!/usr/bin/perl -w use Tk; use strict; my $mw = MainWindow->new; $mw->geometry("200x100"); $mw->title("Text Test"); $mw->Text(-background => 'cyan', -foreground => 'white')->pack(-side => "top"); MainLoop; |
执行该脚本并在窗口中键入该脚本将生成 GUI 应用程序,如图 3 所示。
在此示例中,文本小部件是使用主窗口作为父窗口创建的:
$mw->Text(-background => 'cyan', -foreground => 'white')->pack(-side => "top"); |
不是仅更改背景颜色,前景字体颜色也会更改。与以往一样,pack
方法用来分配空间和显示小部件。
入口小部件类似于文本小部件,可以在此部件中编辑或输入文本。文本小部件可让您输入多行文本,入口小部件只能输入一行文本。
请输入下面的脚本:
#!/usr/bin/perl -w use Tk; use strict; my $mw = MainWindow->new; $mw->geometry("200x100"); $mw->title("Entry Test"); $mw->Entry(-background => 'black', -foreground => 'white')->pack(-side => "top"); MainLoop; |
执行该脚本并在窗口中键入该脚本将生成 GUI 应用程序,如图 4 所示。
文本小部件和入口小部件的唯一差别在于小部件的名称:
$mw->Entry(-background => 'black', -foreground => 'white')->pack(-side => "top"); |
但是,正如该示例所示,您仅能提供一行文本。
当按钮小部件被最终用户激活后,可创建一个可执行函数或命令的按钮。几乎所有的图形程序都包括按钮,因此,可以非常方便地熟悉按钮小部件。
以下示例使用三个按钮。第一个按钮标记为 Button 1,显示消息 Button 1 pushed 和“OK”按钮。第二个按钮标记为 Button 2,显示消息 Button 2 pushed 和“Yes”与“No”按钮,询问用户是否希望退出程序。根据所单击的按钮,将显示一条新消息,指示单击了“Yes”还是单击了“No”按钮,程序退出还是不退出。
以下是一个示例脚本:
#!/usr/bin/perl -w use Tk; use strict; my $mw = MainWindow->new; $mw->geometry("200x100"); $mw->title("Button Test"); my $button1 = $mw->Button(-text => "Button #1", -command => \&button1_sub)->pack(); my $button2 = $mw->Button(-text => "Button #2", -command => \&button2_sub)->pack(); sub button1_sub { $mw->messageBox(-message => "Button 1 Pushed", -type => "ok"); } sub button2_sub { my $yesno_button = $mw->messageBox(-message => "Button 2 Pushed. Exit?", -type => "yesno", -icon => "question"); $mw->messageBox(-message => "You pressed $yesno_button!", -type => "ok"); if ($yesno_button eq "Yes") { $mw->messageBox(-message => "Ok, Exiting.", -type => "ok"); exit; } else { $mw->messageBox(-message => "I didn't think so either.", -type => "ok"); } } MainLoop; |
执行此脚本将生成 GUI 应用程序,如下面的图 5 至图 11 所示。
此脚本比前面的示例更为复杂,但是,如果分析一下,它与其他示例一样并不太复杂。首先,创建每个按钮,并赋予适当的文本(Button #1
或 Button #2
)。每个按钮都与一个命令或函数链接。子例程相应地称为 button1_sub
和 button2_sub
:
my $button1 = $mw->Button(-text => "Button #1", -command => \&button1_sub)->pack(); my $button2 = $mw->Button(-text => "Button #2", -command => \&button2_sub)->pack(); |
单击 $button1
后,将执行 button1_sub
子例程。在此函数内,将创建一个消息框,其中显示文本 Button 1 Pushed 和一个标记为“OK”的按钮。由于不对“OK”按钮执行更多评估,所以,将取消该消息框,主窗口将重新获得焦点。
sub button1_sub { $mw->messageBox(-message => "Button 1 Pushed", -type => "ok"); } |
此子例程类似于第一个示例,只是它包括两个标记为“Yes”和“No”的按钮。用户单击一个按钮时,就会出现一个新消息框,询问单击了哪个按钮。然后,显示另一个消息框,询问是否要退出该程序。
sub button2_sub { my $yesno_button = $mw->messageBox(-message => "Button 2 Pushed. Exit?", -type => "yesno", -icon => "question"); $mw->messageBox(-message => "You pressed $yesno_button!", -type => "ok"); if ($yesno_button eq "Yes") { $mw->messageBox(-message => "Ok, Exiting.", -type => "ok"); exit; } else { $mw->messageBox(-message => "I didn't think so either.", -type => "ok"); } } |
标签 是一个不可编辑的文本小部件。在文本框和入口框之前,标签框非常有用。请输入下面的示例脚本:
#!/usr/bin/perl -w use Tk; use strict; my $mw = MainWindow->new; $mw->geometry("200x100"); $mw->title("Entry Test"); $mw->Label(-text => "What's your name?")->pack(-side => "left"); $mw->Entry(-background => 'black', -foreground => 'white')->pack(-side => "right"); MainLoop; |
执行此脚本将生成 GUI 应用程序,如图 12 所示。
第一行创建一个带有文本 What's your name? 的标签:
$mw->Label(-text => "What's your name?")->pack(-side => "left"); $mw->Entry(-background => 'black', -foreground => 'white')->pack(-side => "right"); |
若要将该标签定位到入口小部件的左侧,可以将 pack
设置为左对齐。与前面的示例一样,入口小部件是使用黑白背景创建的。若要将入口定位到标签小部件的右侧,可将 pack
设置为右对齐。
现在您已经熟悉了几个小部件,下面我们将在一个脚本中实际应用它们:
#!/usr/bin/perl -w use Tk; use strict; my $mw = MainWindow->new; $mw->geometry("500x200"); $mw->title("All-In-One Test"); my $main_frame = $mw->Frame()->pack(-side => 'top', -fill => 'x'); my $top_frame = $main_frame->Frame(-background => "red")->pack(-side => 'top', -fill => 'x'); my $left_frame = $main_frame->Frame(-background => "black")->pack(-side => 'left', -fill => 'y'); my $right_frame = $main_frame->Frame(-background => "white")->pack(-side => "right"); $top_frame->Label(-text => "All-In-One Test!", -background => "red")->pack(-side => "top"); $left_frame->Label(-text => "Enter text to copy", -background => "black", -foreground => "yellow")->pack(-side => "left"); my $copy_entry = $left_frame->Entry(-background => "white", -foreground => "red")->pack(-side => "left"); my $copy_button = $left_frame->Button(-text => "Copy Text", -command => \©_entry)->pack(-side => "right"); my $clear_text = $right_frame->Button(-text => "Clear Text", -command => \&clear_entry)->pack(-side => "top"); my $paste_text = $right_frame->Text(-background => "white", -foreground => "black")->pack(-side => "top"); sub clear_entry { $paste_text->delete('0.0', 'end'); } sub copy_entry { my $copied_text = $copy_entry->get(); $paste_text->insert("end", $copied_text); } MainLoop; |
执行此脚本将生成 GUI 应用程序,如图 13 所示。
我们像其他示例那样分析一下该示例。第一,构建一个主框架并在其中构建三个框架。这些框架包括其他小部件,并保持它们井然有序:
my $main_frame = $mw->Frame()->pack(-side => 'top', -fill => 'x'); my $top_frame = $main_frame->Frame(-background => "red")->pack(-side => 'top', -fill => 'x'); my $left_frame = $main_frame->Frame(-background => "black")->pack(-side => 'left', -fill => 'y'); my $right_frame = $main_frame->Frame(-background => "white")->pack(-side => "right"); |
接下来,添加以下标签:一个在顶部框架,另一个在左侧框架:
$top_frame->Label(-text => "All-In-One Test!", -background => "red")->pack(-side => "top"); $left_frame->Label(-text => "Enter text to copy", -background => "black", -foreground => "yellow")->pack(-side => "left"); |
在左侧框架中的标签旁边,创建一个入口小部件,以便用户能够键入他们想复制的文本。还可以使用按钮小部件来执行复制功能,将该文本复制到右侧框架的文本小部件中:
my $copy_entry = $left_frame->Entry(-background => "white", -foreground => "red")->pack(-side => "left"); my $copy_button = $left_frame->Button(-text => "Copy Text", -command => \©_entry)->pack(-side => "right"); |
接下来让我们看看右侧框架。按钮小部件可让用户清除文本小部件中的所有文本:
my $clear_text = $right_frame->Button(-text => "Clear Text", -command => \&clear_entry)->pack(-side => "top"); my $paste_text = $right_frame->Text(-background => "white", -foreground => "black")->pack(-side => "top"); |
还需要创建一个文本小部件,以便用户可以从入口小部件中复制文本,并在必要时进行编辑。
这些函数是干净的副本子例程:
sub clear_entry { $paste_text->delete('0.0', 'end'); } sub copy_entry { my $copied_text = $copy_entry->get(); $paste_text->insert("end", $copied_text); } |
clear_entry
函数用于删除从 0.0(即 0 行 0 字符)开始直至并包括该部件结尾的所有文本。copy_entry
函数用于获取入口小部件中的文本,并将其插入到文本小部件中。
将带有 Perl/Tk 模块的 Perl 引入 AIX 环境可以让开发人员、管理员、客户和最终用户受益。您可以改进对客户而言非常单调无趣的脚本,使其成为有专业外观的 GUI 应用程序。熟悉这些小部件可能需要一些时间,但是,您掌握了这些技术之后,就会感到付出时间和精力确实值得!
|
Adam Cormany 是一位 UNIX 系统工程师,从事 AIX、Solaris 和 Red Hat Linux 管理已有 10 多年。他是一位 pSeries® AIX 系统管理方面的 IBM eServer® 认证专家。除管理外,Adam 还在 BASH、CSH 和 KSH 的 Shell 脚本以及使用 C、PHP 和 Perl 编程方面具有的渊博的知识。您可以通过 与他联系。 |