前面我们学习了turtle绘制图形文字的一些用法,这一节主要学习Tkinter。Tkinter是python进行GUI编程的高效工具,类似于VC中的MFC,集成了许多控件,如按钮、标签、菜单、文本框等。前面我们在terminal中用sudo apt-get install python-tk安装了Tkinter,所以在py文件中加上from Tkinter import * (也有的是from tkinter import *),即可使用其中的控件和函数。
1. Tkinter入门
首先,举一个小例子:
#coding=utf-8
from Tkinter import *
def processOk():
print ("OK button is clicked.")
def processCancel():
print ("Cancel button is clicked")
# 创建一个窗口
window = Tk()
# 创建两个按钮
btOk = Button(window,text = "OK", fg = "red", command = processOk)
btCancel = Button(window,text = "cancel", bg = "yellow", command = processCancel)
# 将按钮置在窗口上
btOk.pack()
btCancel.pack()
# 创建一个事件循环,监测事件发生,直到窗口关闭
window.mainloop()
这个例子的运行结果为:
点击OK按钮,会在控制台显示OK button is clicked,点击取消按钮亦是。
1)例子中btOk = Button(window, text = "OK", fg = "red", command = processOk)是创建一个按钮,其中第一个参数,通常是该控件的父容器,这里指的是该button是在window中的;第二个参数是该按钮的显示内容;第三个参数是前景色(对应的bg为背景色,见第二个按钮创建);第四个参数command,是指当鼠标点击这个按钮时触发的事件函数,这里是processOK函数。
2)btOk.pack()是将按钮在window中一行接着一行布局。
3)window.mainloop()这句创建一个事件循环,它会不停的捕捉在window内的事件直到window关闭,如果触发某个函数则执行,如本例中的点击按钮操作。
2. Tkinter的各种GUI控件
这一节介绍几个常见的Tkinter控件,python中叫做widgets。
Button:简单的按钮,用来执行触发操作,如上例;
Canvas:帆布,结构化的图形界面,可以在上面绘制各种图形,进行图形编辑;
Checkbutton:复选框;
Entry:文本编辑区域,类似于MFC中的text field或text box;
Frame:框架,用来包含其他控件,主要用于控制界面布局;
Label:文本或图片显示;
Menu:菜单;
Menubutton:菜单按钮;
Message:显示文本,和Label控件类似,但是Message可以根据文本的长度自动调整显示;
Radiobutton:单选按钮;
Text:格式化文本显示,允许编辑文本的显示风格和属性。
下面举个例子(其中用到了Checkbutton、Radiobutton、Frame、Entry、Label、Message、Text、Button控件):
#coding=utf-8
from Tkinter import *
class WidgetsDemo:
def __init__(self):
window = Tk() # 创建一个窗口
window.title("Widgets Demo") # 设置标题
frame1 = Frame(window) # 创建一个框架
frame1.pack() # 将框架frame1放置在window中
self.v1 = IntVar()
# 创建一个复选框,如果选中则self.v1为1,否则为0,当点击cbtBold时,触发processCheckbutton函数
cbtBold = Checkbutton(frame1,text="Bold",variable=self.v1,
command=self.processCheckbutton)
self.v2 = IntVar()
# 创建两个单选按钮,放置在frame1中,按钮文本是分别是Red和Yellow,背景色分别是红色和黄色,
# 当rbRed按钮被选中时self.v2为1,当rbYellow按钮被选中时,self.v2为2,按钮被点击时触发processRadiobutto函数
rbRed = Radiobutton(frame1,text="Red",bg="red",
variable=self.v2,value=1,
command=self.processRadiobutton)
rbYellow = Radiobutton(frame1,text="Yellow",bg="yellow",
variable=self.v2,value=2,
command=self.processRadiobutton)
# grid布局
cbtBold.grid(row=1,column=1)
rbRed.grid(row=1,column=2)
rbYellow.grid(row=1,column=3)
frame2 = Frame(window) # 创建框架frame2
frame2.pack() # 将frame2放置在window中
label = Label(frame2,text="Enter your name: ") # 创建标签
self.name = StringVar()
# 创建Entry,内容是与self.name关联
entryName = Entry(frame2,textvariable=self.name)
# 创建按钮,点击按钮时触发processButton函数
btGetName = Button(frame2,text="Get Name",
command=self.processButton)
# 创建消息
message = Message(frame2,text="It is a widgets demo")
# grid布局
label.grid(row=1,column=1)
entryName.grid(row=1,column=2)
btGetName.grid(row=1,column=3)
message.grid(row=1,column=4)
# 创建格式化文本,并放置在window中
text = Text(window)
text.pack()
text.insert(END,"Tip\nThe best way to learn Tkinter is to read")
text.insert(END,"these carefully designed examples and use them")
text.insert(END,"to create your applications.")
# 监测事件直到window被关闭
window.mainloop()
# 复选框点击按钮函数
def processCheckbutton(self):
print ("Check button is:"
+ ("checked" if self.v1.get() == 1 else "unchecked"))
# 单选按钮点击函数
def processRadiobutton(self):
print (("Red" if self.v2.get() == 1 else "Yellow")
+ " is selected.")
# Get Name按钮点击函数
def processButton(self):
print ("Your name is " + self.name.get())
WidgetsDemo()
该例子的运行结果为:
1)self.v1 = IntVar()表示v1是Int型变量;
2)cbtBold = Checkbutton()这一句中variable = self.v1表示与v1关联,默认情况为当该按钮选中时,v1=1,否则v1=0;rbRed = Radiobutton()这一句中也有类似的,其中value=1表示该按钮选中是v2=1,若选中rbYellow,则v2=2;
3)cbtBold.grid(row=1,column=1)与之前的pack()函数一样,都是布局函数,不过这里是在Frame中划分行列,并在特定行列显示;
4)text.insert(END," ")是指向Text中插入格式化文本,其中END是指将文本插入到当前文本的后面;
5)另外,可以像下面这样修改控件的参数:rdRed["text"] = "This Is Red" ;rdRed["cursor"] = "plus"(光标到这里变成十字);
6)self.name.get()函数可以获得变量内容。
3. Canvas
Canvas类似于一个画板,可以在上面绘制各种图形和进行图形编辑,Canvas的坐标系不同于turtle的坐标系,它是以canvas的左上角点为原点(0,0),以右方和下方为x轴正轴和y轴正轴,并以像素为单位;下面介绍几个常用的绘制函数:
create_rectange(x1,y1,x2,y2):绘制一个矩形,(x1,y1)为矩形左上角点,(x2,y2)为矩形右下角点;
create_oval(x1,y1,x2,y2):绘制一个椭圆,(x1,y1)和(x2,y2)分别为椭圆外接矩形的左上角点和右下角点;
create_arc(x1,y1,x2,y2,start,extent):绘制一个弧形, (x1,y1)和(x2,y2)分别为椭圆或圆外接矩形的左上角点和右下角点,start是弧形角度开始点,extent是弧形角度;
create_polygon(x1,y1,x2,y2,x3,y3):绘制一个多边形,(xi,yi)分别为各顶点坐标;
create_line(x1,y1,x2,y2):绘制线条,(x1,y1)和(x2,y2)分别为起始点和结束点;
create_text(x,y,text):绘制字符串在以(x,y)为中心的位置。
下面举个小例子说明用法:
window = Tk()
canvas = Canvas(window,width=200,height=100,bg="white")
canvas.pack()
canvas.create_rectangle(10,10,190,90,tags="rect")
#canvas.create_oval(10,10,190,90,fill="red",tags="oval")
#canvas.create_arc(10,10,190,90,start=0,extent=90,width=8,fill="red",tags="arc")
#canvas.create_polygon(10,10,190,90,30,50,tags="poly")
#canvas.create_line(10,90,190,10,width=9,arrow="last",activefill="blue",tags="line")
#canvas.create_text(60,40,text="string",font="Times 10 bold underline",tags="string")
#canvas.delete("rect","oval","arc","poly","line","string")
window.mainloop()
对其中出现的一些字段做简要说明:create_rectangle()中的tags表示的是这个图形在canvas中的标识,在后面的canvas.delete()(删除canvas中的图形)中也使用到;create_oval()中的fill表示的是填充颜色;create_arc()中的width表示的是图形线段的宽度;create_line中的arrow="last"表示在线段末尾加箭头,active fill表示若鼠标移动到这条线段上时,线段的颜色会变成蓝色;create_text()中的font是字体。
4. Geometry Managers
Tkinter利用Geometry Managers在容器中布置控件,有三种Geometry managers:grid,pack,place。其中前两种在之前使用过。每一种管理方式都不同,所以通常不在一个容器中混合使用这三种方式,而是利用Frame子容器来分开使用geometry managers。
1)grid
grid的通常表示方式是:widgets.grid(row=a, column=b, rowspan=c, columnspan=d, padx=e, pady=f, sticky=E)。其中前两个参数已经用过,rowspan和columnspan表示控件跨几行几列;padx和pady表示与容器的水平边线和垂直边线间隔多少像素值;sticky表示在容器内容的什么方位,有E,S,N,W,SE,SW,NW,NE几种。具体可测试。
2)pack
上面的例子,默认pack的方式是一行一行进行的。pack中可以用side来设置放置的方式,有LEFT, RIGHT, TOP, BOTTOM,默认的方式就是TOP,如widget.pack(side=LEFT)。
3)place
place可以在任何位置放置控件,用法为widgets.place(x=a,y=b),a,b分别为坐标。值得注意的是,place manager并不兼容所有的计算机,如果windows的分辨率为1024*768,那么place正好可用,若分辨率过高或过低,都会出现显示问题。
5. 使用图片
可以用photo = PhotoImage(file = imagefilename)来加载图片。然后在控件的创建中使用图片。如
testImage = PhotoImage(file = "testimage.gif")
Label(window,image=testImage)
canvas.create_image(90,50,image=testImage)
Button(window,image=testImage)