图形用户界面(Graphical User Interface),简称GUI,指采用图形方式显示的计算机操作用户界面。Python提供了多个GUI库,常用的有Tkinter,wxPython以及Jython,其中Tkinter模块儿(TK接口)是Python标准TK GUI工具包的接口,这里只介绍Tkinter模块儿,注:Python2.7ttk是直接导入的,ttk是自己的包,Python3.x版本都改为tkinter,t小写,ttk是包含在tkinter里面。
一、Tkinter编程
- 导入Tkinter模块儿(或 from Tkinter import*)
- 创建顶层窗口对象,用于容纳GUI, eg:top = Tkinter.Tk(),top为根窗口,frame = Tkinter.Frame(top),frame是顶层窗口
- 在顶层窗口对象中构建所有GUI组件及其功能
- 通过底层应用代码将这些GUI组件连接起来
- 进入mainloop()事件循环
下面示例代码:在Tkinter实例化中进行3、4步。
import Tkinter
#弹窗信息
from tkMessageBox import showinfo
class App:
#初始化,传入顶层窗口参数
def __init__(self,top=None):
#Button控件
self.hi_there=Tkinter.Button(top,text='Hi',fg='blue',command=self.say_hi)
#三种布局管理器,最原始的Placer,网格坐标Grid,以及常用的Packer
self.hi_there.pack(side=Tkinter.TOP)
def say_hi(self):
showinfo(title='Hi',message='Hello, welcome to the GUI world!')
if __name__ == '__main__':
#创建根窗口对象
top=Tkinter.Tk()
#Tkinter实例化
app=App(top)
#进入事件循环
top.mainloop()
注:3,4步骤是混合使用的;顶层窗口可以有多个,但是根窗口只能有一个
1、根窗体对象的常用函数:
- top.title('标题'):修改窗体名字
- top.geometry('500x500'):窗体对象的大小
- top.quit():退出
- top.update():刷新页面
- ...
2、pack控件设置位置属性参数:
- anchor:控件对齐方式,N、E、S、W、NW、NE、SW、SE、CENTER(默认值为CENTER)
- side:控件在窗体的相对位置,LEFT,RIGHT,TOP,BOTTOM
- fill:控件填充方式,X水平,Y垂直,BOTH水平和垂直,NONE不填充
- expand:1可扩展,0不可扩展
- ...
二、常用控件
在Tkinter中,每个组件都是一个类,上面第三步构建某个组件实际上是将该类进行实例化,在实例化过程中,
控件 |
描述 |
Button
按钮控件,与Label相似,除此之外提供鼠标悬浮,按下,释放以及键盘活动/事件
Canvas
画布控件;显示图形元素如线条或文本
CheckButton
多选框控件;用于在程序中提供多项选择框(与Html的checkbox类似)
Entry
输入控件;用于收集键盘输入
Frame
框架控件;在屏幕上显示一个矩形区域,多用来作为容器
Label
标签控件;可以显示文本和位图
Listbox
列表框控件;在Listbox窗口小部件是用来显示一个字符串列表给用户
Menubutton
菜单按钮控件,用于显示菜单项。
Menu
菜单控件;按下MenuButton后弹出的选项列表,显示菜单栏,下拉菜单和弹出菜单
Message
消息控件;与Label类似,用来显示多行文本,与label比较类似
Radiobutton
单选按钮控件;显示一个单选的按钮状态(与Html的radio类似)
Scale
范围控件;显示一个数值刻度,为输出限定范围的数字区间
Scrollbar
滚动条控件,当内容超过可视化区域时使用,为Text、Canvas、Listbox、及Enter等支持的控件提供滚动功能
Text
文本控件;用于显示多行文本
Toplevel
容器控件;用来提供一个单独的对话框,和Frame比较类似
Spinbox
输入控件;与Entry类似,但是可以指定输入范围值
PanedWindow
PanedWindow是一个窗口布局管理的插件,可以包含一个或者多个子控件。
LabelFrame
labelframe 是一个简单的容器控件。常用与复杂的窗口布局。
tkMessageBox
用于显示你应用程序的消息框。showinfo(title='',message='')
下面来介绍几种典型的控件
三、Label控件
实例化代码示例如下(实际上,大部分控件的实例化方式都是这样,也可以不采用类的方式)
import Tkinter
from Tkinter import PhotoImage
class App():
def __init__(self,top=None,photo=None):
label=Tkinter.Label(top,text="干啥呢?啥都要看?嗯?")
label.pack(side=Tkinter.LEFT)
imglabel=Tkinter.Label(top,image=photo)
imglabel.pack(side=Tkinter.RIGHT)
if __name__ == '__main__':
top=Tkinter.Tk()
photo=PhotoImage(file="warnning.gif")
app=App(top,photo)
top.mainloop()
注:python中image属性仅支持gif、pgm、ppm格式
四、Button控件
此控件实现一个简单的按钮,关联python函数,来响应用户的一个点击操作,当按钮被按下时,自动调用该函数。更简单的理解:按钮就是一个特殊的标签Label,只不过多了点击响应的功能。
import Tkinter
from Tkinter import StringVar
from tkMessageBox import showinfo
#关联的函数
def ChangeText():
var.set("你怎么还点!")
def showBox():
showinfo(message="左边不可以点,右边的按钮就可以点了吗?嗯?")
#根窗口对象
top=Tkinter.Tk()
#顶层窗口对象
frame1=Tkinter.Frame(top)
frame2=Tkinter.Frame(top)
var=StringVar(top)
var.set("不许点下面左边的按钮!")
#Label控件
label=Tkinter.Label(frame1,textvariable=var,justify=Tkinter.LEFT)
label.pack(side=Tkinter.LEFT)
photo = Tkinter.PhotoImage(file="warnning.gif")
imglabel = Tkinter.Label(frame1, image=photo)
imglabel.pack(side=Tkinter.RIGHT)
# 按钮控件
Buttonleft = Tkinter.Button(frame2, text="嘿嘿嘿", command=ChangeText)
Buttonleft.pack(side=Tkinter.LEFT)
Buttonright = Tkinter.Button(frame2, text="嘻嘻嘻", command=showBox)
Buttonright.pack(side=Tkinter.RIGHT)
frame1.pack(padx=10, pady=10)
frame2.pack(padx=10, pady=10)
if __name__ == '__main__':
top.mainloop()
点击左侧“嘿嘿嘿”按钮之后,图片Label内容修改如下
点击右侧“嘻嘻嘻”按钮之后,弹出txMessageBox弹框如下
Button控件常用属性如下:
- text:字符串,按钮的文本内容,eg:text="嘿嘿嘿"
- activebackground:鼠标按下去,按钮的背景 {MOD},eg:activebackground='red'
- activeforeground:鼠标按下去,按钮的前景 {MOD},eg:activeforeground='white'
- fg(foreground):按钮文本的颜 {MOD}
- bg(background):按钮背景 {MOD}
- font:字体样式和大小,eg:font=('Helvetica',12,'bold'),font=("微软雅黑",15)
- image:给按钮设置一张图像
- justify:LFET,CENTER,RIGHT,显示多行文本时,不同行之间对齐方式
- padx:单位像素,按钮在x轴上的内边距,按钮内容距离按钮边缘的距离
- pady:单位像素,y轴方向上的内边距
- textvariable:指定变量名,变量值转变为字符串在控件上显示,当前变量值改变,控件也自动刷新
- anchor:锚选项,控制文本文职,默认为中心
五、Entry控件
单行文本输入,接收用户输入,区别于Text控件,Entry只能单行输入,Text可以多行输入,但是二者都可以通过get()方法,获取文本框内容,如果要修改文本框内容,则需要调用insert()方法
- delete(first,last=None):删除字符
- get():返回当前控件字符串
- insert(index,s):在给定索引处的字符之前插入字符串s
- entry['state'] = 'readonly' :设置为只读属性
- Entry与Label和Button不同,它的text属性无效,需用textvariable属性绑定字符串变量
- entry = Entry(root,show="*"):密码输入不可见
如下是较常见的采用pack布局管理器的Entry控件,覆盖了Entry常用方法
import Tkinter
from Tkinter import*
#清除text内容
def clear():
entry.delete(0, END)
#初始化text内容
def init():
entry.delete(0, END)
entry.insert(0, "Please input here")
top=Tkinter.Tk()
var=StringVar()
entry=Tkinter.Entry(top,text=var,font=("微软雅黑",15))
var.set("Please input here")
entry.pack()
#构建clear按钮
button=Tkinter.Button(top,text='clear',activeforeground='white',activebackground='blue',command=clear)
button.pack(side=Tkinter.LEFT)
#构建insert按钮
buttoninsert=Tkinter.Button(top,text='init',activeforeground='white',activebackground='green',command=init)
buttoninsert.pack(side=Tkinter.RIGHT)
entrytest=Tkinter.Entry(top,text=var,font=("微软雅黑",5))
#只读属性
entrytest['state']='readonly'
entrytest.pack()
#获取输入框内容
print entry.get()
if __name__ == '__main__':
top.mainloop()
注:StringVar(),是tcl相应的对象,除set函数外,还有get函数。
如下是较常见的采用Grid布局管理器的Entry控件,覆盖了Entry常用方法
import Tkinter
from Tkinter import *
from tkMessageBox import showinfo
top=Tkinter.Tk()
def submit():
if e1.get()=='pangpang' and e2.get()=='pangpang':
showinfo(title='',message='welcome to Entrytest')
else:
showinfo(title='',message='Wrong user or pwd')
def clear():
e1.delete(0,END)
e2.delete(0,END)
label1=Tkinter.Label(top,text='User: ')
label1.grid(row=0)
label2=Tkinter.Label(top,text='Pwd: ')
label2.grid(row=1)
e1=Tkinter.Entry(top)
e1.grid(row=0,column=1,padx=10,pady=5)
e2=Tkinter.Entry(top,show='*')
e2.grid(row=1,column=1,padx=10,pady=5)
submit=Tkinter.Button(top,text='submit',activeforeground='white',activebackground='blue',fg='red',bg='green',command=submit)
submit.grid(row=2,column=0)
clear=Tkinter.Button(top,text='clear',activeforeground='white',activebackground='blue',fg='red',bg='green',command=clear)
clear.grid(row=2,column=1)
top.mainloop()
六、RadioButton控件
RadioButton为Button控件的一种,单选按钮控件,实例化代码示例如下:
import Tkinter
from Tkinter import *
from tkMessageBox import showinfo
top = Tkinter.Tk()
#显示选项值
def showoption():
showinfo(title='',message=str(v.get()))
v=IntVar()
#设置各个选项
# r1=Tkinter.Radiobutton(top,text='option1',variable=v,value=1,command=showoption)
# r1.pack()
# r2=Tkinter.Radiobutton(top,text='option2',variable=v,value=2,command=showoption)
# r2.pack()
# r3=Tkinter.Radiobutton(top,text='option3',variable=v,value=3,command=showoption)
# r3.pack()
#采用循环的方式增加option选项
Options=[('option1',1),('option',2),('option3',3)]
for option,num in Options:
r=Tkinter.Radiobutton(top,text=option,variable=v,value=num,command=showoption)
r.pack(anchor=W)
if __name__ == '__main__':
top.mainloop()
注:在属性设置中,indicatoron=False可以将小圈圈改成按钮的形式;在pack()方法中设置anchor=W,N,E,CENTER等值,可以让其显示在不同位置。
七、CheckButton控件
CheckButton为Button控件的一种,多选控件,实例化代码如下:
import Tkinter
from Tkinter import *
top = Tkinter.Tk()
v=[]
Options=['option1','option',2,'option3']
for option in Options:
v.append(IntVar())
r=Tkinter.Checkbutton(top,text=option,variable=v[-1])
r.pack(anchor=W)
if __name__ == '__main__':
top.mainloop()
八、Listbox控件
此控件一般应用于选项比较多,显示为列表的情况,实例化代码示例如下:
import Tkinter
from Tkinter import *
top=Tkinter.Tk()
listbox=Tkinter.Listbox(top,setgrid=True)
listbox.pack()
#删除选项
def delete():
listbox.delete(ACTIVE)
for list in ['python','java','c#','c++']:
listbox.insert(END,list)
deletebutton=Tkinter.Button(top,text='删除',font=('微软雅黑',15),activeforeground='white',activebackground='red',fg='black',bg='blue',command=delete)
deletebutton.pack()
if __name__ == '__main__':
top.mainloop()
九、Scrollbar控件
如果将Listbox控件里的显示列表扩展如下,那么结果图,最后的php几个就不会显示了,需要用户滚动鼠标,但是正常情况下从用户体验角度来说用户基本不会想到去滚动鼠标的,这样就有了Scrollbar控件
['python','java','c#','c++','ruby','c','html','js','css','jquery','bootstrap','php']
import Tkinter
from Tkinter import *
top=Tkinter.Tk()
scrollbar=Tkinter.Scrollbar(top)
#滚动条设置在左边,竖着滚动
scrollbar.pack(side=Tkinter.LEFT,fill=Y)
#将listbox设置滚动条
listbox=Tkinter.Listbox(top,yscrollcommand=scrollbar.set)
listbox.pack(side=Tkinter.RIGHT,fill=BOTH)
#让滚动条可以滚动listbox内容
scrollbar.config(command=listbox.yview)
for list in ['python','java','c#','c++','ruby','c','html','js','css','jquery','bootstrap','php']:
listbox.insert(END,list)
if __name__ == '__main__':
top.mainloop()
在了解了上述控件之后可以发现控件实例化的步骤相差不多,只是不同控件的默认参数设置和方式不同而已,对于不同控件参数设置等,只能多写写了,熟能生巧吧。