Chapter 1. Hello, Perl/Tk
内容:
Perl/Tk Concepts
Some Perl/Tk History
Getting Started with Perl/Tk
Hello World Example
Unsolicited Advice
Debugging and PrototypingPerl/Tk Programs
TK 是一个模块让你可以用Perl创建图形接口, 很多Per程序是用命令行写的,
可能使麻烦的和恐吓的 对于终端用户。
Perl/TK 让你和按钮,菜单,对话框,滚动条 文本框
所有的功能你需要开发简单的或者复杂的GUI 应用
为什么使用一个图形接口? 你的编程经历,你可能大概遇到一些基于文本的即可使不能满足你的需要,
某些应用允许不需要输入,但是其他的, 比如安装脚本,需要用户不断的输入信息。
他们问一下问题如下:
你需要安装这个文件吗?
我可以覆盖整个DLL?
你需要创建这个目录? 你需要帮助文件?
一个图形用户窗口(GUI) 添加一点天赋和专业到一个应用,这里有一些好的GUI的例子:
1. 一个迷你的web客户端,连接到一个目录服务器
2.一个应用显示一个地图在一个滚动窗口
3.一个程序即可 和数据库显示查询结果在几个部件里, 使用labels来描述数据
4.一个mail reader 使用接口在你的收件箱里,也可以发送消息
一个GUI 可以是有用的,当你的老板说 让它更易于使用,通常意味着 增加一个脚本的封装
或者一个接口让它变得更简单
但这并不意味着 你应该开始增加GUIs到你所有的Perl脚本。
有时候 它会意味着 过度的增加GUI到你的脚本.
如果所有你要做的是读取一个文件,不需要用户输入,生成另外一个文件,
一个GUI会变得没有必要的, GUIs最好的当你需要大量的决定和输入,比如安装情况:
1.1. Perl/Tk Concepts
Perl/Tk 程序是用面向对象类型的,但是你不需要之前有Perl面向对象经验来编码 在Perl/Tk。
你会很容易的捡起来 在你看到第一个例子后。
简而言之,Perl/Tk 部件(比如按钮和列表框) 是对象 他们有方法 我们调用来控制他们。
除了部件,Perl/Tk有images, 也是对象,和字体
一个Perl/Tk程序 是有分层的部件组成的。 分层的顶级部件是MainWindow,
父部件对于所有其他的部件在一个应用里。
MainWindow 部件表现为一个容器, 里面部署子部件使用布局管理器。
部件层次是重要的, 除此之外, 它对于部件管理器是有用的来控制屏幕布局和菜单系统来安排菜单系统。
每个不同的部件属于一个类,一个部件的类定义它的初始外观和行为,
但是同样类的单独的部件可以自定义
比如,你可以创建2个按钮有不同的文本标签。
有时 你可以读取实例化的一个对象。
着是一个简单的面向对象创建的小部件,类构造器是负责创建部件实例
类也定义了一个部件的初始行为通过创建bindings,一个Binding 关联一个event
比如一个按钮 按下 调用一个回调,
这是子程序处理事件。 你可以增加额外的bindings(事实上,事件改变和删除他们)
改变一个部件的标准行为,回调有几个不同的格式, 但是我们最多使用简单的引用到Perl函数。
1.2. Some Perl/Tk History 一些Perl/Tk历史:
Perl/Tk 有他的父节点 在X Windows 系统,和Tcl语言。 所以让我们绕过到历史页面,
给你一些主义 Perl/Tk来自哪里 ,如何来到这里
1.2.1. The X Window System and Xlib X视窗和Xlib
X windows 系统(也被它的朋友称为X或者X11) 首次发布在1987年作为一个图形平台用于Unix 系统。
和很多的Unix软件一样,X 应用几乎都是用C语言写的,使用一个library 比如Xt, Motif, or
(如果你确实很不幸运或者 真的勇敢) 依赖的库是基于 applications, Xlib.
Xlib有优势,你可以做任何事情, 例如:
这里有一种方式来让一个简单的pull-down 菜单使用Xlib( 这是Tk的一个声明)
首先,确定最长的菜单项的尺寸。
为了轮转,假设菜单标签字符串是在C变量 menu_item.
子函数XTextExtents 决定几个menu_item的几个指标,
比如它的总体宽度 像素 在当前字体和他的像素高度,
通过计算最大上升和下降( 像素在基线上下)
1.2.2. The Coming of Tcl/Tk
工具命令语言(Tcl) 在1987年开发
早几年前, 控制数据公司可嵌入的概念, 扩展的命令语言到一个逻辑的结论使用它的操作系统
命令语言被称为 系统命令语言(SCL)
但是Ousterhout 被需要来提供它的主意,由于对GUIs感兴趣,
他设计了一个图形组建的工具包
他认为这种方式更加有效的相比写C语言代码,
甚至使用一个工具包像Motif。
它的直觉被证明是正确的, 它的图形包叫做TK
早在1991年, Ousterhout 发布了Tk版本1.0,图形扩展到Tcl脚本语言。
Tk的高层部件集(使用Xlib作为它的绘图包)
1.2.3. The Evolution of Perl/Tk Tk的进化
一个早期的 TkPerl "Hello World" program:
如果这个看来起奇怪, 记住它是8年前的事务的状态, 当TkPerl 是alpha
Perl的面向对象的特习仍旧是beta.
注意 pack还没有变成一个部件方法, 被命名为tkpack
因此它和perl内置的函数不冲突。
Figure 1-1. Hello, Perl/Tk
这个窗口使用下面的Perl 一行代码创建:
1.2.4. Perl/Tk Meets Win32 满足Win32
1.3. Getting Started with Perl/Tk 开始学习Perl/Tk
足够的历史, 这个章节其余部分是关于使用Tk的基本知识,包含如何创建简单的部件和显示他们,
一个基于事件程序的快速介绍, 一个应该的"Hello World" example.
在我们继续开始前,让我们确保已经安装了一切。
1.3.1. Do You Need To Install Anything? 你需要安装一切吗?
自动tk扩展没有跟随Perl标准版本的发布,第一件事情你应该做的是确保安装Tk版本
不管你是运行在Win32或者Unix,perl程序应该在你的path里, 输入下面的命令:
% perl -v
特别的, 注意版本在第一行,
如果 Tk模块是可用的通过使用这个命令:
% perl -e "use Tk"
如果你没有得到下面的错误:
Can't locate Tk.pm in @INC (@INC contains: C:PERLlibsite ...
假设 Tk是可以运行的,你可以查看他的版本:
[root@dr-mysql01 sbin]# perl -MTk -e 'print "$Tk::VERSION
"'
804.033
最好的方式验证 都是好的是运行一个部件掩饰程序
Perl/Tk Versions
这本书是基于 Perl 5.6.0 and Tk 800.022。
当Perl/Tk 803.xxx 变得可用, 期望它是线程安全的和 Unicode (UTF-8)
1.3.2. Creating Widgets 创建部件:
所有的部件在Perl/Tk程序是被创建相同的基本方式,少数除外。
每个部件必须有一个唯一的父部件来照看它, 它被出啊不敢见和跟踪它
当它存在应用里,当你创建一个应用,你会有一个中央的窗口 会包含其他部件。
通常那个窗口回事所有部件的父窗体 。
假设 $parent 部件已经存在,一般使用当你创建部件 部件类型如下:
$child = $parent->Widgettype( [ -option => value, . . . ] );
注意 变量存储在部件里是标量(实际上, 他们是部件对象的引用,
但是你不需要现在知道)
如果你不熟悉面向对象的语法 , using the -> 在$parent和部件类型调用方法,部件类型来自$parent对象
如果让$parent 和子$child 联系在一起。
你可能在猜测,$parent 变成父部件被创建。
一个parent 可以有很多个child,但是一个child 只能有一个parent
1.3.3. Specifying Options 指定选项:
当你调用部件类型方法,你通常指定配置参数来设置部件和应用互动。
配置参数会成对出现:
一个选项(比如 -text, -state, or -variable) 和它的相关的值。
每个选项以破折号开始, 但是这只是规定。
选择只是字符串用于表明如何解释他们相关的值。
通常情况下, 它是不需要把引号加在选项名字上,因为Perl是足够智能的来识别他们作为字符串。
然而, 如果你是用-w switch.
Perl 可能抱怨一个选项,认为它不是文本。
你可以给你的文本加上引号来避免这个问题
选项在列表中被指定:
(-option => value, -option => value, -option => value)
如果你从来没有在Perl里看过=>, 它只是不同的方式来说"comma",
除了 =>操作符 自动引号,消除可能的歧义。
例如,下面的代码工作正常,下面的代码工作正常 因为自动引号剞劂语境作为字符串:
sub text {}
$mw->Label(-text => 123);
然而,使用逗号语法,-text 解析为-&text( ):
$mw->Label(-text, 123);
记住这点, 你仍旧可以使用知识逗号 不是=>符号,比如:
(-option, value, -option, value, -option, value)
但是,它是很难告诉 哪个是键值对。考虑下面的语法相同语句
( 每个都创建一个按钮部件 ,10 * 10的像素,显示单词"Exit",
执行退出应用的动作 。
$bttn = $parent->Button(-text, "Exit", -command, sub { exit }, -width, 10, -height, 10);
$bttn = $parent->Button(-text => "Exit", -command => sub { exit }, -width => 10, -height => 10);
在第2行, 它是更明显的参数配对在一起
另外喜欢 的选项/值 规定的语法使用Perl的qw 操作符, 作为列表的参数:
这种类型更像Tcl的语法,有空格分隔的标记。
你倾向于打更少的字符。
字符串分隔符通常是()或者{},
但是//是最常用的,因为它不需要一个转换。
注意 qw 拆分简单的单词,因此选项值可以只是简单的单词,
不是多字符引用字符串,代码引用, 着就是为什么我们移动 -command选项到qw 字符串结束。
1.3.4. Toplevel, MainWindow, and Frame Widgets 顶级窗体,主窗口和Frame 部件
另一个迂回的时候,在下面的几个章节,我们会使用部件在我们的例子里,
我们可能没有覆盖。
我们相信我们会找出 他们中大数据是什么意思从上下文看 ,但是需要一些简短的介绍:
MainWindow 和 Toplevel 是窗口(或者不见--我们经常互换) 包含其他部件。
MainWindow 是指定一个Toplevel 部件的版本,MainWindow 是第一个window 你需要创建在你的应用了。
其他类型的部件 你需要知道是一个Frame 部件,一个Frame 是一个容器可以包含其他部件。
它通常是无形的,只是用于按需要安排部件。
当然, 还有更多, 有关更多信息,请参见第11章,“框架、主窗口和顶层的小部件”。
1.3.5. Displaying a Widget 显示一个部件:
创建一个部件和显示它是不一样的,你需要 使用2个单独的符号来创建一个部件
和显示它。
尽管有时他们结合到同一条线,看起来像一个单独的命令。
到目前为止的示例中,我们已经使用Button 方法来创建按钮,
但是什么也没有显示通过单独的使用这个方法。
代替的是我们需要使用布局管理器来引起部件被显示在他的父窗体或者在其他的部件。
最长用的布局管理器是pack,使用它,你可以简单的调用pack方法在部件对象,如下:
$widget->pack( );
For example:
$button->pack( );
参数你可以发送pack方法是在Chapter 2, "Geometry Management".介绍:
没有必要调用pack方法在单独的行,->pack 可以被增加到创建的小部件
$parent->Button(-text => "Bye!", -command => sub { exit })->pack( );
另外布局管理器是grid, form 和place 所有4个
1.3.6. The Event Loop 事件循环:
当编程时使用一个应用程序,使用一个图形接口相比一个文本接口,
你需要重新思考你的方法 应用的流程。
在一个基于文本的应用,你可以从标准输入读取,使用命令行选项,读文件,或者提示用户对于特定的信息。
键盘是你的主要的输入途径,在一个GUI,输入不仅来自那些地方,
还来自于鼠标和窗口管理器。
尽管这些额外的输入允许更多的灵活性 在你的应用系统里。
例如, 一个close 指令从一个windows 管理器比如mwm 或者MS窗口:
输入一个GUI 定义为事件, 事件是典型的不同于组合 使用键盘和鼠标,
如果用户点击左边的鼠标 按钮 在Button "B",
那是一种event .点击右边的按钮 在Button "C" 是另外一个事件。
输入字母a 是另外一个事件,按住ctrl键并单击 鼠标中间按钮 是另外一个事件。
Events 可以来自输入和输出操作或者 在程序控制下生成。
事件处理在一个event loop,event loop 顾名思义,在一个循环中处理事件。
它决定了什么字过程被调用基于什么样的事件发生 这是一个伪代码事件循环:
while (1) {
get_event_info
if event is left-mouse-click call process_left_mouse_click
else if event is right-mouse-click call process_right_mouse_click
else if event is keyboard-input call type_it
else handle events for redrawing, resizing etc
}
这是一个显然的简单的方法对于一个event loop, 但它显示了基本的想法。
event loop 是淘汰过程来确定 什么类型的输入已经给了应用。
在Perl/Tk,event loop 是通过调用一个函数发起 被称为Mainloop.
任何在这个语句之前的都是设置界面,任何代码在这个请求之后的不会执行
在本书中,我们使用$mv 来表明变量,指向MainWindow 被应用开始就创建
如果我们忘记了包括 Mainloop 语句,程序会思考一段时间然后回到命令提示符。
1.4. Hello World Example 例子
每一个编程语言通过Hello World", 它是一个完整的程序 打印字符串(通常是"Hello World")
然后退出. Hello World 可能会嘲笑, 但它是一个非常有效的工具
向读者展示了如何编写和执行一个程序 当他们仍旧在这本书的第一章。
#!/usr/bin/perl
use Tk;
my $mw = MainWindow->new;
##标题
$mw->title("Hello World");
$mw->Button(-text => "Done", -command => sub { exit })->pack;
MainLoop;
尽管只有6行,第一行,调用Perl 第2行告诉perl使用Tk库。
在Unix, Win32 你需要输入perl hello.pl 来执行程序或者
第三行:
my $mw = MainWindow->new;
我们如何创建窗口,窗口会有相同的基本窗口管理器
我们窗口的标题是通过使用title 方法改变的,如果我们不使用这个方法。
文本在窗口顶部会和包含代码的文件名字一样, 不包含任何扩展信息。
任何字符串 我们输入作为参数变为标题,如果我们需要标题为"Hey"!
看我伟大的程序 这将是整个地方
下一行是创建一个按钮部件,设置基本的属性, 然后pack部件
设置按钮来显示text "Done" 和执行perl命令exit 当按钮被push.
最后关心的条目是MainLoop 命令。
这个开始事件爱你循环,
1.5.未经请求的建议
1.5.1。编程风格
Perl/Tk 脚本的代码可以相当繁琐和笨重的 ,因为所有的选项/值 对 用于定义和配置 每个部件。
这里有几种方式来排版代码处理可读性( 在某些情况下,编辑能力).
大多数 你设计增加额外的空间或者表格到代码的不同部分, 一旦你习惯看到代码,它不会显得那么神秘而笨拙.
编码风格放置每个键值对在单独一行
$bttn = $parent->Button(-text => "my text",
-command => sub { exit },
-width => 10,
-height => 10);
这种风格, 它是非常明显 键值对是什么和相关选项的值 。
$bttn = $parent->Button(
-text => "Exit",
-command => sub { exit },
-width => 10,
-height => 10,
);
这使得代码更加容易编辑, 一个选项/值 对可以被增加或者删除 在每行 不需要混乱 逗号,分好或逗号。