使用Perl/Tk把GUI加入服务器编程

作为系统程序员,您习惯性地使用命令行界面。可能您已不了解用轻量级图形用户界面(graphical user interface,GUI)来包装现有的功能是多么地容易。新发布的 Perl/Tk 及时地提醒您高质量有时候伴随着易用性。

您可以把精力集中放在高产量的服务器端编程上,而有时仍然可选择使界面更漂亮。此外,轻量级工具箱(例如 Perl/Tk)使这样做成为可能并且使您不必付出更为引人注目的 GUI 方法的代价。

工具箱纵览

代价是什么?一般来说,与 GUI 的对应的面向命令行的亲戚相比,GUI 的编程、测试、移植和部署更为困难。人们广泛认可 Microsoft Visual Basic(VB)对 GUI 构造的简化。然而,VB 实际上被孤立在 Windows 世界中,作为一门编程语言,它显得有点简陋,这些问题约束了 VB;如果您想详细了解这些缺点,请参阅本文末尾的参考资料。虽然 Java、GTK+ 和 Qt 已被人们接受并用于 Linux 和相关的开放源代码开发,但是为了开始使用它们,您需要花去很多时间来学习并编写很多行代码;它们的“进入门槛”阻碍了从面向字符编程向 WIMP(windows-icons-menus-pointers,窗口-图标-菜单-指针)编程的悄然转变。

虽然用户交互的 Web 模型过于简化,但对于许多小任务来说,它已足够了。事实上,我的大部分 GUI 编程是关于 Web 应用程序的。

然而,有时候 Web 的模型是不够的。您需要更成熟的可编程性或不同的安全性模型。有时候,您只是需要“另一个源”;Web 服务器的基于 Web 的控制面板会使系统太脆弱。有时候,Web 的模型太大了:常见的服务器和客户机使用很多内存并需要配置。

但是,我有好消息。请保持高产量的系统编程习惯。请使用轻量级高级语言绑定(例如 Perl/Tk 或 Tkinter)。您将得到您已开发的程序的可移植的、可维护的、“GUI 化”的版本,这些版本能够良好地运行,您将对此感到惊奇。

无论您喜爱的语言是 Ruby 还是 Fortran,正确的附件都将给您类似的机会。下面是一个已熟悉 Perl 的程序员成功的例子。

准备学习 Perl/Tk

您了解 Perl。它很简洁,而且这种简洁是巧妙的,这使您能在五分钟内编写报告生成器、网络探测、文本过滤器和进程监视器,如果使用其他语言的话需一天的时间才能完成。

然而,您可能不知道,只要再加几行代码,您就能把 Perl 应用程序变为表现出色、漂亮的 GUI 应用程序。在 developerWorks 上有一篇 Teodor Zlatanov 的文章(请参阅参考资料,其中有这篇文章的链接),这篇文章描述了 cfengine 和相关的 Perl 实用程序,还为您演示如何编写易用的工具,例如关闭所有 inetd 进程的短小的脚本:

清单 1. kill_inetd.pl 的源代码

use Proc::ProcessTable;

$t = new Proc::ProcessTable;

foreach $p (@{$t-table}) {

# note that we will also kill "xinetd" and all processes

# whose command line contains "inetd"

kill 9, $p-pid if $p-cmndline =~ 'inetd';

}

如果您需要关闭几个有问题的 CGI 进程,怎么办?或者,如果您需要比相当残酷的“kill 9”更得体地发送信号,怎么办?如果您不在的时候您的老板或后备人员需要使用这个脚本,怎么办?传统的答案是打开编辑器、把 inetd 替换成 cgi 等,然后从命令行再次运行 perl kill_inetd.pl。

然而,请把第一个清单转换成清单 2:

清单 2. 修改后的 kill_inetd.pl 的源代码

use Proc::ProcessTable;

use Tk;

sub kill_them {

$t = new Proc::ProcessTable;

foreach $p (@{$t-table}) {

kill $signal, $p-pid if $p-cmndline =~ $keyword;

}

$result_text = "Signal $signal sent to all '$keyword' processes.";

}

$main = MainWindow-new();

$main-Label(-text =

"Control panel for killing processes\n

enter keyword here")-pack();

$main-Entry(-textvariable = \$keyword)-pack();

$radiobutton_frame = $main-Frame-pack();

$radiobutton_frame-Radiobutton(-text = "KILL",

-variable = \$signal,

-value = 9)-pack(-side = left);

$radiobutton_frame-Radiobutton(-text = "TERM",

-variable = \$signal,

-value = 15)-pack(-side = left);

$main-Button(-text = "Send kill signal to named processes",

-command = \&kill_them)-pack();

$main-Label(-textvariable = \$result_text)-pack();

# Set reasonable defaults.

$keyword = "inetd";

$signal = 9;

MainLoop();

当您在运行清单 2 时,您将得到一个较小的但有用的 GUI 控制面板:

简单的信号发送控制面板

用户把它弹出一次后就可以方便地使用它而不必再输入。

不过,请注意这二十一行的脚本为您省去的东西:您没有长达几页的声明和配置。您没有任何许可证限制(除了您熟悉的 Perl 许可证)。您不必学习新的语言。

新的地平线

这是令人兴奋的东西。您可以使用简短的 GUI 脚本来包装所有的、现存的、用 Perl 代码编写的应用程序以使它们成为同样交互的、“方便用户”的程序。事实上,您可以容易地重写您现有的实用程序以使它们能够在收到合适的命令行参数时继续以正常的“批处理”方式运行,但在其他情况下能够执行另一个分支并构造 GUI 窗口:

清单 3. 在命令行与 GUI 操作之间作出选择

sub batch_operation {

}

sub start_GUI {

use Tk;

...

MainLoop();

}

if (0 == scalar(@ARGV)) {

start_GUI();

}

if (errors_detected_in_@ARGV()) {

start_GUI();

}

batch_operation();

请记住:为了取得这些结果,您只需添加几行您已知道的 Perl(或 Python 或……)代码。此外,因为对于外部应用程序来说,Perl 起到“粘合剂”的作用,所以这些技术可被用来包装您不想碰的旧的 Fortran 或 C 应用程序。您只需用一点带有反引号(backtick)或 exec 的 Perl 来包装它们就可以了。

Perl/Tk 还有不错的可伸缩性。全世界每天正在使用大量的 Perl/Tk 应用程序,包括生化模拟器、地图绘制程序、航班管理系统等。表达大规模的 Perl/Tk 编程的感觉是困难的。以上的示例演示了通过添加几行 Perl 来“GUI 化”是多么的容易。如果您想更充分地体会“大规模”的 Perl/Tk 编程的感觉,请参阅下面的参考资料中的参考书并自己研究更为复杂的程序的源代码。

一个我还没写的程序(虽然我已写了这个程序的原始的原型)是 Zlatanov 的遗传算法模拟器(请阅读他在 developerWorks 发表的文章中有关这个模拟器的内容,这篇文章被列在参考资料中。)的图形版本。作为练习,读者可以编写一个更令人满意的版本。我自己的实验暗示这将是本专栏所推荐的方法的范例:当它的批处理方式的操作在易用的 Perl/Tk Canvas 小窗口上被可视化时将变得确实很生动。

如果您在几年前就试用过 Perl/Tk 且 Perl/Tk 没给您留下深刻的印象,那么现在是再给 Perl/Tk 一次机会的时候。最近 Perl/Tk 的处理器有了很大的改进。对于 Perl/Tk 的初学者来说,在流行的平台上安装二进制文件的过程被大大地简化,Windows 的可移植性也有了改善,最新的发行版的质量更高。有关 Perl/Tk 的书越来越多,这一点也许更为重要。O'Reilly 在七月推出了 Perl in a Nutshell 的第二版,其中有宝贵的 Perl/Tk 的参考资料。最好的消息是 O'Reilly 在 2002 年初出版了由 Nancy Walsh 和 Stephen Lidie 编写的 Mastering Perl/Tk。如果您准备较长时间的使用 Perl/Tk,那么 Mastering Perl/Tk 是一本您需要购买的参考书。

结束语

在系统程序员和管理员看来,GUI 工作可能有点神秘。它类似于专业的工作,这种工作不包括我们一般在“服务器诊所”中进行的那些开发。

然而,它不必是那个样子。类似 Perl/Tk 的现代的 GUI 工具箱提供了不错的性能和功能以及本专栏经常强调的高产量和易学性。请您在这个月花一两个小时,给 Perl/Tk 一次帮您包装程序的机会以使程序更有吸引力。

· 把年龄相仿的狮虎熊放一起,谁更厉害?结果出人意料

很多人都想知道狮子、老虎和熊打起来谁最厉害,于是便有好事之人把这三种动物关在一起...

· 湖北宜昌三峡坝区水面惊现神秘动物

近日,湖北宜昌,一段视频在当地热传:有网友在三峡坝区拍到神秘动物,体型硕大数米长...

· 什么是语段?语段的类型以及和句群、段落的区别与联系是什么?

句群是最高级的语言单位。 段落(自然段)是章法单位...

 
Perl Web 服务器初级编程
Perl Web 服务器初级编程 Perl Web 服务器初级编程 如果你对WEB服务器编程和LINUX环境下PERL CGI编程感兴趣,建议你阅读下面内容,即使没有CGI开发经验,只要了解perl语言,就不会感觉困难。由...查看完整版>>Perl Web 服务器初级编程
 
Perl Web 服务器初级编程
如果你对WEB服务器编程和LINUX环境下PERL CGI编程感兴趣,建议你阅读下面内容,即使没有CGI开发经验,只要了解perl语言,就不会感觉困难。由于我第1次写作Blog文章,如有错误请指出,谢谢。 HTTP消息...查看完整版>>Perl Web 服务器初级编程
 
Java高级编程:使用打印服务API
Java自从问世以来在各方面发展迅速,但是一直以来,打印输出是java最弱的方面。事实上,java1.0不支持任何打印功能。Java1.1在java.awt包里包含了一个叫做PrintJob的类,但是这个类提供的打印功能十分粗糙和不可靠。...查看完整版>>Java高级编程:使用打印服务API
 
Perl/TkFAQ-10.11.那些格式的图片可以在Perl/Tk中使用?
  原文:  10.11. What Image types are available?  In addition to the Tk builtin bitmaps there is support for reading images from files in formats such as: X11 Bitmaps (.xbm), X Pixmaps (.xpm), a...查看完整版>>Perl/TkFAQ-10.11.那些格式的图片可以在Perl/Tk中使用?
 
Perl/TkFAQ-12.9如何了解我所使用的Perl/Tk的版本?
  原文:  12.9. How do I determine the version of perl/Tk that I am running?  With an up to date perl installation one may query the local perl setup and all extensions via the command: perldoc ...查看完整版>>Perl/TkFAQ-12.9如何了解我所使用的Perl/Tk的版本?