码迷,mamicode.com
首页 > 编程语言 > 详细

19 图形用户界面编程 - 《Python 核心编程》

时间:2015-08-21 00:00:15      阅读:579      评论:0      收藏:0      [点我收藏+]

标签:

?? 引言
?? Tkinter 与Python 编程
?? Tkinter 模块
?? Tk 组件库
?? Tkinter 使用举例
?? 标签、按钮与进度条组件
?? 一个使用 Tk 的中级范例
?? 其他 GUI 简介(Tix, Pmw, wxPython, PyGTK)
?? 相关模块和其他 GUI
Python 的默认GUI 工具集是Tk,它也是我们将使用的最基本的GUI 工具集。
我们可以通过Python 接口Tkinter 来使用Tk(Tkinter 正是“Tk 接口”之意)。 
Tk 并非“最强、最新”也不是包含GUI 构建模块最多的工具集,但它非常简单,并且可以开发 出能运行于大多数平台的GUI 程序。
19.1 简介
什么是Tcl、Tk 和Tkinter?
        Tkinter 是Python 的默认GUI 库,它基于Tk 工具集,后者最初是为工具命令语言(Tcl)设计
    的。Tk 流行后被移植到许多其他脚本语言中,包括Perl(Perl/Tk)、Ruby(Ruby/Tk)和 Python
    (Tkinter)。借助于Tk 开发GUI 的可移植性和灵活性,加上脚本语言的简洁和系统语言的强劲,我
    们得到了一件可与商业软件相匹敌的利器,它可以用于快速开发各种GUI 程序。
        Python 基于Tk 提供了一种更高效的快速原型系统用以创建应用。
        别忘了您同时还享有Python 的系统访问、网络操作、XML、数字可视化、数据库访问、以及所有其他标准库和第三方模块。
安装和使用Tkinter
    类似于线程模块,系统中的Tkinter 未必是默认开启的。
    通过尝试导入Tkinter 模块 来判断它是否能被Python 解释器使用。
客户端/服务器架构
        窗口系统就是软件服务 器的另一个例子,它们运行在一个有显示设备的机器上,比如带有一个某种类型的显示器。当然还 
    有客户端(那些需要窗口环境来运行的程序,也就是我们所说的GUI 程序),这些程序无法脱离窗口 系统单独运行。
19.2 Tkinter 与 Python 编程
Tkinter 模块:把Tk 引入您的程序
    要创建并运行您的GUI 程序,下面五步是基本的:
        1. 导入Tkinter 模块(import Tkinter,或者,from Tkinter import *)。
        2. 创建一个顶层窗口对象,来容纳您的整个GUI 程序。
        3. 在您的顶层窗口对象上(或者说在“其中”)创建所有的GUI 模块(以及功能)。
        4. 把这些GUI 模块与底层程序代码相连接。
        5. 进入主事件循环。
GUI 程序开发简介
        创建GUI 程序与画家作画有些相似。通常画家只会在一块画布上开展自己的创作。工作步骤或
    许是这样的:首先要找来一块干净的石板,您将在这个“顶层”窗口对象上创建所有其他模块。可
    以把这一步想象成一座房屋的地基或者某个画家的画架。换言之,在搭建各实物或展开画布之前,
    您必须先给地基浇灌好混凝土或者架好画架。对Tkinter 而言,这个基础被称为顶层窗口对象
   
        在GUI 程序中,会有一个顶层根窗口对象,它包含着所有小窗口对象,它们共同组成一个完整
    的GUI 程序。这些小窗口对象可以是文字标签、按钮、列表框等等。这些独立的GUI 构件就是所谓
    的组件。所以当我们说创建一个顶层窗口的时候,我们实际上是指您需要一个放置所有组件的地方。
 
    典型的Python 语句如下行:
        top = Tkinter.Tk() # 如果上文是“from Tkinter import *",Tk()就够了
 
        Tkinter.Tk()返回的对象通常被称作根窗口,正因为如此,有些程序用root 来指示它,而非top
    顶层窗口是指那些在您的程序中独立显示的部分。您可以在GUI 程序中创建多个顶层窗口,但它们
    中只能有一个是根窗口。您可以采用先完全设计好组件再添加实际功能的开发方式,也可以二者同
    时进行。(这意味着交替执行上述五步中的第三步和第四步。)
    
        组件既可以是独立的也可以作为容器存在。如果一个组件“包含”其他组件,它就被认为是这
    些组件的父组件。相应地,如果一个组件被“包含”在其他组件中,它就被认为是父组件的孩子, 
    父组件则是直接包围其外的那个容器组件。
 
        通常,组件会有一些相应的行为,例如按钮被按下,或者文本框被写入。这种形式的用户行为
    被称为事件,而GUI 程序对事件所采取的响应动作被称为回调
 
        用户操作包括按下(以及释放)按钮、移动鼠标、按下RETURN 或Enter 键等等,所有的这些从
    系统角度都被看作事件。GUI 程序正是由这伴随其始末的整套事件体系所驱动的。这个过程被称作
    件驱动处理
 
        一个事件及其回调的例子是鼠标移动。我们假设鼠标指针停在您GUI 程序的某处。如果鼠标被
    移到了程序的别处,一定是有什么东西引起了屏幕上指针的移动,从而表现这种位置的转移。系统
    必须处理这些鼠标移动事件才能展现(并实现)鼠标在窗口上的移动。一旦您释放了鼠标,就不再
    会有事件需要处理,相应地,屏幕上的一切又复归平静。
    
        GUI 程序的事件驱动特性恰好体现出它的客户端/服务器架构。当您启动一个GUI 程序时,它必
    须执行一些初始化例程来为核心功能的运行做准备,正如启动一个网络服务器时必须先申请一个套
    接字并把它绑定在一个本地地址上一样。Tk 有两个坐标管理器用来协助把组件放在正确的位置上
    您将经常用到的一个称为“包”,亦即packer。另一个坐标管理器是网格(Grid)--您可以用它来把
    GUI 组件放在网格坐标系中,Grid 将依据GUI 中的网格坐标来生成每个对象。我们将紧扣packer 讲
    解。
 
        一旦packer 决定好您所有组件的尺寸和对齐方式,它将为您在屏幕上放置它们。当所有这些组
    件,包括顶层窗口,最终显示在您屏幕上时,GUI 程序就会进入一个“服务器式”的无限循环。这个
    无限循环包括等待GUI 事件、处理事件、然后返回等待模式,等待下一个事件。
 
        上述最后一步说明所有组件就绪后立即进入主循环。这正是我们提及的“服务器式”无限循环
 
        对Tkinter 而言,相应代码如下:
            Tkinter.mainloop()
 
        这通常是您程序执行的最后一段代码。一旦进入主循环,GUI 便从此掌握控制权。所有其他动作
    都来自回调函数,包括程序退出。当您拉下文件菜单点击“退出”菜单项或直接关闭窗口时,必须
    要唤起一个回调来结束您的程序。
顶层窗口:Tkinter.Tk()
    所有的主要组件都建立在顶层窗口对象内。
    这个对象是由Tkinter 中的Tk 类创建 的,并且是由普通构造函数创建的: 
        >>> import Tkinter
        >>> top = Tkinter.Tk()
    在这个窗口中,您可以放置独立组件或集成的模块来构建您的GUI。
Tk 组件
    Tk 目前有15 种组件。
        核心注释:缺省参数是您的朋友
        GUI 开发从Python 的缺省参数机制获益匪浅,因为Tkinter 组件有大量的默认动作。除非您熟
    知自己使用的每一个组件的每一个可用选项,否则最好只设置您关心的参数而把其他的交由系统处
    理。这些缺省值是精心选出的。
    如果您没有提供这些值也不必担心程序会在屏幕上表现怪异。作为一条基本规则,程序都由一
    系列经优化的缺省值创建,并且只有当您明确知道如何配置您的组件时,才有必要用自己的值替换
    这些缺省值。
    组件                    描述
    Button                 按钮。类似标签,但提供额外的功能,例如鼠标掠过、按下、释放以及键盘操作/事件
    Canvas                画布。提供绘图功能(直线、椭圆、多边形、矩形);可以包含图形或位图
    Checkbutton      选择按钮。一组方框,可以选择其中的任意个(类似HTML 中的checkbox)
    Entry                    文本框。单行文字域,用来收集键盘输入(类似HTML 中的text)
    Frame                  框架。包含其他组件的纯容器
    Label                   标签。用来显示文字或图片
    Listbox                 列表框。一个选项列表,用户可以从中选择
    Menu                  菜单。点下菜单按钮后弹出的一个选项列表,用户可以从中选择
    Menubutton      菜单按钮。用来包含菜单的组件(有下拉式、层叠式等等)
    Message             消息框。类似于标签,但可以显示多行文本
    Radiobutton       单选按钮。一组按钮,其中只有一个可被“按下”(类似HTML 中的radio)
    Scale                   进度条。线性“滑块”组件,可设定起始值和结束值,会显示当前位置的精确值
    Scrollbar             滚动条。对其支持的组件(文本域、画布、列表框、文本框)提供滚动功能
    Text                     文本域。多行文字区域,可用来收集(或显示)用户输入的文字(类似HTML 中的textarea)
    Toplevel             顶级。类似框架,但提供一个独立的窗口容器。
19.3 Tkinter 举例
标签组件   
1 #!/usr/bin/env python
2 
3 import Tkinter
4 
5 top = Tkinter.Tk()
6 label = Tkinter.Label(top, text=Hello World!)
7 label.pack()
8 Tkinter.mainloop()
按钮组件
1 #!/usr/bin/env python
2 
3 import Tkinter
4 
5 top = Tkinter.Tk()
6 quit = Tkinter.Button(top, text=Hello World!,7         command=top.quit)
8 quit.pack()
9 Tkinter.mainloop()
标签和按钮组件
 1 #!/usr/bin/env python
 2 
 3 import Tkinter
 4 top = Tkinter.Tk()
 5 
 6 hello = Tkinter.Label(top, text=Hello World!)
 7 hello.pack()
 8 
 9 quit = Tkinter.Button(top, text=QUIT,
10         command=top.quit, bg=red, fg=white)
11 quit.pack(fill=Tkinter.X, expand=1)
12 
13 Tkinter.mainloop()

标签、按钮和进度条组件

技术分享
    
 1 #!/usr/bin/env python
 2 
 3 from Tkinter import *
 4 
 5 def resize(ev=None):
 6     label.config(font=Helvetica -%d bold %  7             scale.get())
 8 
 9 top = Tk()
10 top.geometry(250x150)
11 
12 label = Label(top, text=Hello World!,
13         font=Helvetica -12 bold)
14 label.pack(fill=Y, expand=1)
15 
16 scale = Scale(top, from_=10, to=40,
17         orient=HORIZONTAL, command=resize)
18 scale.set(12)
19 scale.pack(fill=X, expand=1)
20 
21 quit = Button(top, text=QUIT,
22         command=top.quit, activeforeground=white,
23         activebackground=red)
24 quit.pack()
25 
26 mainloop()
中级Tkinter 范例
  1 #!/usr/bin/env python
  2 
  3 import os
  4 from time import sleep
  5 from Tkinter import *
  6 
  7 class DirList(object):
  8         
  9         def __init__(self, initdir=None):
 10                 self.top = Tk()
 11                 self.label = Label(self.top,
 12                                 text=Directory Lister v1.1)
 13                 self.label.pack()
 14 
 15                 self.cwd = StringVar(self.top)
 16 
 17                 self.dirl = Label(self.top, fg=blue,
 18                                 font=(Helvetica, 12, bold))
 19                 self.dirl.pack()
 20 
 21                 self.dirfm = Frame(self.top)
 22                 self.dirsb = Scrollbar(self.dirfm)
 23                 self.dirsb.pack(side=RIGHT, fill=Y)
 24                 self.dirs = Listbox(self.dirfm, height=15,
 25                                 width=50, yscrollcommand=self.dirsb.set)
 26                 self.dirs.bind(<Double-1>, self.setDirAndGo)
 27                 self.dirsb.config(command=self.dirs.yview)
 28                 self.dirs.pack(side=LEFT, fill=BOTH)
 29                 self.dirfm.pack()
 30 
 31                 self.dirn = Entry(self.top, width=50,
 32                                 textvariable=self.cwd)
 33                 self.dirn.bind(<Return>, self.doLS)
 34                 self.dirn.pack()
 35 
 36                 self.bfm = Frame(self.top)
 37                 self.clr = Button(self.bfm, text=Clear,
 38                                 command=self.clrDir,
 39                                 activeforeground=white,
 40                                 activebackground=blue)
 41                 self.ls = Button(self.bfm,
 42                                 text=List Directory,
 43                                 command=self.doLS,
 44                                 activeforeground=white,
 45                                 activebackground=green)
 46                 self.quit = Button(self.bfm, text=Quit,
 47                                 command=self.top.quit,
 48                                 activeforeground=white,
 49                                 activebackground=red)
 50                 self.clr.pack(side=LEFT)
 51                 self.ls.pack(side=LEFT)
 52                 self.quit.pack(side=LEFT)
 53                 self.bfm.pack()
 54 
 55                 if initdir:
 56                         self.cwd.set(os.curdir)
 57                         self.doLS()
 58         
 59         def clrDir(self, ev=None):
 60                 self.cwd.set(‘‘)
 61 
 62         def setDirAndGo(self, ev=None):
 63                 self.last = self.cwd.get()
 64                 self.dirs.config(selectbackground=red)
 65                 check = self.dirs.get(self.dirs.curselection())
 66                 if not check:
 67                         check = os.curdir
 68                 self.cwd.set(check)
 69                 self.doLS()
 70 
 71         def doLS(self, ev=None):
 72                 error = ‘‘
 73                 tdir = self.cwd.get()
 74                 if not tdir: tdir = os.curdir
 75 
 76                 if not os.path.exists(tdir):
 77                         error = tdir + :no such file
 78                 elif not os.path.isdir(tdir):
 79                         error = tdir + : not a directory
 80 
 81                 if error:
 82                         self.cwd.set(error)
 83                         self.top.update()
 84                         #sleep(2) # sleep ??
 85                         if not (hasattr(self, last)  86                                         and self.last):
 87                                 self.last = os.curdir
 88                         self.cwd.set(self.last)
 89                         self.dirs.config( 90                         selectbackground=LightSkyBlue)
 91                         self.top.update()
 92                         return
 93 
 94                 self.cwd.set( 95                         FETCHING DIRECTORY CONTENTS...)
 96                 self.top.update()
 97                 dirlist = os.listdir(tdir)
 98                 dirlist.sort()
 99                 os.chdir(tdir)
100                 self.dirl.config(text=os.getcwd())
101                 self.dirs.delete(0, END)
102                 self.dirs.insert(END, os.curdir)
103                 self.dirs.insert(END, os.pardir)
104                 for eachFile in dirlist:
105                         self.dirs.insert(END, eachFile)
106                         print eachFile
107                 self.cwd.set(os.curdir)
108                 self.dirs.config(109                         selectbackground=LightSkyBlue)
110 
111 def main():
112         d = DirList(os.curdir)
113         mainloop()
114 
115 if __name__ == __main__:
116         main()
技术分享
19.4 其他GUI 简介

19 图形用户界面编程 - 《Python 核心编程》

标签:

原文地址:http://www.cnblogs.com/BugQiang/p/4743109.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!