python-tk。然后在程序中导入这个模块,便可以利用Tkinter开发应用程序了,导入指令如下:from Tkinter import *或者impython-pport Tkinter推荐记忆和使用前者。 Tkinter是一个经典的Python GUI程序,它由TK GUI工具包包装而来,利用这个模块可以方便地开发一些跨平台的图形界面。在windows和Mac OS下的Python开发包里默认包含这个模块,无需额外安装,而在Unix下需要自己编译安装,指令如下:sudo apt-get install python-tk,然后就可以在程序中导入Tkinter模块并使用它进行应用程序开发,导入指令如下:
from Tkinter import *(推荐使用)
或者
import Tkinter
Tkinter的使用一般分为四个步骤:
下面以一个例子1(建立一个带按钮的窗口界面)来解释说明以上步骤:
#coding:utf-8
#!/usr/bin/python
from Tkinter import *
# 点击button时对应的操作
def say_hello():
print '你好,gui !'
# 根窗口
root = Tk()
root.title('window with command') #主窗口标题
root.geometry('400x200') #主窗口大小,中间的为英文字母x
# 次级窗口
com = Button(root,text = '打招呼', command = say_hello) # 第一个参数root说明com按钮是root的孩子,text指按钮的名称,command指点击按钮时所执行的操作
com.pack(side = BOTTOM) # 次级窗口的位置摆放位置
# 事件循环
root.mainloop()
运行结果如下:
首先 root = Tk()产生一个根窗口,并通过title()和geometry()方法来设置根窗口的标题和大小,根窗口只应该创建一次,并且在其他窗口创建之前被创建。
接着,创建次级窗口,这里是Button,其中的参数分别是指这个按钮是根窗口的孩子,按钮的名称,以及点击按钮时执行的相应的操作。pack()方法
它告诉相应的Button窗口部件去调整自己的位置和尺寸,并且使用自己可见。其中的side参数指代窗口摆放的位置,通常有TOP, BOTTOM, LEFT, RIGHT四个参数,分别指代上下左右。
通常情况下,用面向对象的方式来重写代码,这样可扩展性和修改性比较好,如下:
# coding:utf-8
#!env/usr/bin/python
from Tkinter import *
class App(object):
def __init__(self,master):
self.com = Button(master,text = '打招呼', command = self.say_hello)
self.com.pack(side = BOTTOM)
def say_hello():
print '你好,Gui!'
root = Tk()
root.title('window with command')
root.geometry('400x200')
app = App(root)
root.mainloop()
Tkinter支持的核心窗口部件有15个,其列表如下,列表为转载。
部件 | 描述 |
---|---|
Button | 一个简单的按钮,用于执行命令或其他操作。 |
Canvas | 结构化图形,该部件可用于绘制图形或图表、创建图形编辑器以及实现定制部件。 |
Checkbutton | 代表一个可拥有两个不同值的变量,点击按钮可以在两个值之间进行切换。 |
Entry | 一个文本输入框。 |
Frame | 一个容器部件。该框架可以拥有一个边框和背景,当创建一个程序的程序或对话布局时可用于集合其他部件 |
Label | 显示一个文本或图像。 |
Listbox | 显示一个替换列表。该列表框可被设置为接收单选框或清单行为。 |
Menu | 一个菜单面板。用于实现下拉和弹出菜单项。 |
Menubutton | 一个菜单按钮。用于实现下拉菜单项。 |
Message | 显示一个文本。类似于标签部件,但可以将文本自动绑定为给定的宽度或宽高比。 |
Radiobutton | 代表可拥有多个值的变量的一个值。点击按钮可使变量获取该值并同时清除所有与该变量相关的复选框按钮 |
Scale | 允许你通过拖拽"滑块"来设置数值 |
Scrollbar | 用于画板、输入框、列表框和文本部件的标准滚动条 |
Text | 格式化文本显示。允许你使用各种样式和属性显示或编辑文本。同时还支持嵌入图像或窗口。 |
Toplevel | 作为一个分割的顶层窗口显示的容器部件 |
这里,将利用Button来建立路灯演示牌,在给出源代码之前先介绍代码中三个基本知识:占位符%r和%s的不同、偏函数和lambda操作符。
简单地说: %r 是 repr, 而%s 是str;
也就是说用%r的占位符将显示带引号的字符串,而用%s的占位符显示的是字符串的内容,具体事例如下:
>>> str = 'Hello, world!'
>>> print '%s' % str
Hello, world! # 不带引号
>>>print '%r' % str
'Hello, world!' # 带引号的字符串
首先给出《Python核心编程》的定位,偏函数应用(partial function application,PFA),这种函数将任意数量(顺序)的参数的函数A(a1,a2)提供给另一个带剩余参数的函数B(A, a3,a4.......)的对象。
下面举例说明以上定义: 例如对于加法函数 add(a,b,c,d,e,f,g): return a+b+c+d+e+f+g
当我们要计算七个数的加和的时候,需要每次传入七个参数,但是,如果我们固定其中的6个参数(如,它们的值分别为1,2,3,4,5,6)时,只让一个参数变化时,仍然每次传递七个参数就显得有点麻烦。
如果我们利用偏函数来操作,那么操作将简便的多,如下:
add_using_partial = partial(add,1,2,3,4,5,6)
此时,我们要计算当前六个参数固定只有最后一个参数变化时的加和结果,只需如: add_using_partial(7), add_using_partial(100)等
引入偏函数对编写具有多参数的Tk组件具有很多优势,它能够允许你预存一些函数变量并有效的冻结了这些预定参数,在运行时你获得了所需其他变量后再把它解冻出来,用这些最终确定的参数去调用
函数。
lambda关键字通常被用来创建匿名函数,匿名函数不需要以标准的方式来声明,比如说,使用def语句.
举个简单例子:
标准函数定义和使用:
#标准函数定义
def func(x):
return x**2
print func(4) #标准函数使用
匿名函数的定义和使用:
func = lambda x: x**2
func(4)
lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边是返回值。
当然也有没有参数的匿名函数,如
lambda :True #等价于 def true(): return True
#coding:utf-8
from functools import partial as pto
from Tkinter import *
from tkMessageBox import showinfo,showwarning,showerror
WARN = 'warn'
CRIT = 'crit'
REGU = 'regu'
SIGNS = {
'do not enter': CRIT,
'railroad crossing': WARN,
'55\nspeed limit': REGU,
'wrong way': CRIT,
'merging traffic': WARN,
'one way': REGU }
# 匿名函数
critCB = lambda: showerror('Error', 'Error Button Pressed!')
warnCB = lambda: showwarning('Warning', 'Warning Button Pressed!')
infoCB = lambda: showinfo('Info', 'Info Button Pressed!')
top = Tk()
top.title('Road Signs')
Button(top, text = 'QUIT', command = top.destroy,
bg = 'red', fg = 'white').pack()
# 偏函数
MyButton = pto(Button, top)
CritButton = pto(MyButton, command = critCB, bg = 'white',fg = 'red')
WarnButton = pto(MyButton, command = warnCB, bg = 'goldenrod1')
ReguButton = pto(MyButton, command = infoCB, bg = 'white')
for eachSign in SIGNS:
signType = SIGNS[eachSign]
cmd = '%sButton(text = %r%s).pack(fill = X, expand = True)' %(
signType.title(),eachSign, '.upper()' if signType == CRIT else '.title()')
eval(cmd)
top.mainloop()
运行结果如下:
2. Listbox —— 建立两个可以相互交换内容的列表
#coding:utf-8
from Tkinter import *
class App(object):
"""
建立左右两个列表,两个列表中的内容可以通过左右按钮交换
"""
def __init__(self,root):
self.language = 'Python','Perl','C','Ruby','PHP','Java'
self.leftbox = StringVar()
self.leftbox.set(self.language)
self.rightbox = StringVar()
self.rightbox.set('')
self.list_left = Listbox(root, listvariable = self.leftbox, width = 16)
self.list_left.pack(side = LEFT)
self.frame = Frame(root)
self.frame.pack(side = LEFT)
Button(self.frame, text = '->', command = self.move_to_right, width = 7).pack(side = TOP)
Button(self.frame, text = '<-', command = self.move_to_left, width = 7).pack(side = TOP)
self.list_right = Listbox(root, listvariable = self.rightbox)
self.list_right.pack(side = RIGHT)
def move_to_right(self):
"""
将左列表中的内容移动到右列表中,用Listbox中的curselection()方法来捕捉鼠标选中的条目
用delete()方法删除选中条目,用insert(END,)方法来向列表尾插入条目
"""
self.list_right.insert(END,self.list_left.get(self.list_left.curselection()))
self.list_left.delete(self.list_left.curselection())
def move_to_left(self):
self.list_left.insert(END,self.list_right.get(self.list_right.curselection()))
self.list_right.delete(self.list_right.curselection())
if __name__ == '__main__':
root = Tk()
app = App(root)
root.mainloop()
运行结果如下: