Python程序设计应用教程 第7章 Tkinter图形界面设计

7.1 Python图形开发库

Python提供了多个图形开发界面的库,几个常用的Python GUI(Graphical User Interface)库如下:

(1)Tkinter:IDLE也是用Tkinter编写而成;

(2)wxPython;

(3)Jython:Jython程序可以和Java无缝集成。除了一些标准模块,Jython使用Java的模块。Jython几乎拥有标准的Python中不依赖与C语言的全部模块。Jython可以被动态或静态地编译成Java字节码。

7.1.1 创建Windows窗口

import tkinter    #导入Tkinter模块
win=tkinter.Tk()    #创建Windows窗口对象
win.title('我的第一个GUI程序')    #设置窗口标题
win.mainloop()    #进入消息循环,也就是显示窗口

窗口对象.geometry(宽度x高度)    #设置窗口的大小,x是小写字母x

#还可以使用minsize()方法设置窗口的大小
窗口对象.minsize(最小宽度,最小高度)
窗口对象.maxsize(最大宽度,最大高度)
#例如:
win.minsize("400x600")
win.maxsize("1440x800")

7.1.2 几何布局管理器

Tkinter几何布局管理器(Geometry Manager)用于组织和管理父组件(往往是窗口)中子组件的布局方式。Tkinter提供了3中不同的布局管理器:pack、grid和place。

1.pack几何布局管理器

pack()方法提供如下表所示的若干参数选项

选项 描述 取值范围
side 停靠在父组件的哪一边 'top'(默认值)、'bottom'、‘left’、'right'
anchor 停靠位置,对应于东南西北以及4个角 'n'/'s'/'e'/'w'/'nw'/'sw'/'se'/'ne'/'center'(默认值)
fill 填充空间 'x'/'y'/'both'/'none'
expand 扩展空间 0或1
ipadx,ipady 组件内部在x/y方向上填充的空间大小 单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点)

padx,pady

组件外部在x/y方向上填充的空间大小

单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点)
import tkinter
root=tkinter.Tk()
label=tkinter.Label(root,text='hello,python')
label.pack()    #将Label组件添加到窗口中显示
button1=tkinter.Button(root,text='BUTTON1')    #创建文字是'Button1'的Button组件
button1.pack(side=tkinter.LEFT)    #将button1组件添加到窗口中显示,左停靠
button2=tkinter.Button(root,text='BUTTON2')
button2.pack(side=tkinter.RIGHT)
root.mainloop()

2.grid几何布局管理器

grid几何布局管理采用表格结构组织组件。子组件的位置由行/列确定的单元格决定。每一列中,列宽由这一列中最宽的单元格确定。grid几何布局管理器适合于表格形式的布局。

grid()方法提供如下表所示的若干参数选项

选项 描述 取值范围
sticky 组件紧贴所在单元格的某一边角,对应于东南西北以及4个角 'n'/'s'/'e'/'w'/'nw'/'sw'/'se'/'ne'/'center'(默认值)
row 单元格行号 整数
column 单元格列号 整数
rowspan 行跨度 整数
columnspan 列跨度 整数
ipadx,ipady 组件内部在x/y方向上填充的空间大小 单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点)

padx,pady

组件外部在x/y方向上填充的空间大小

单位为c(厘米)、m(毫米)、i(英寸)、p(打印机的点)

如果不指定row,会将子组件放置到第一个可用的行上;如果不指定column,则使用第0列(首列)

from tkinter import *
root=Tk()
#200x200代表了初始化时主窗口的大小,280、280代表了初始化时窗口所在的位置
root.geometry('200x200+280+280')
root.title('计算器示例')
#Grid网格布局
L1=Button(root,text='1',width=5,bg='yellow')
L2=Button(root,text='2',width=5)
L3=Button(root,text='3',width=5)
L4=Button(root,text='4',width=5)
L5=Button(root,text='5',width=5,bg='green')
L6=Button(root,text='6',width=5)
L7=Button(root,text='7',width=5)
L8=Button(root,text='8',width=5)
L9=Button(root,text='9',width=5,bg='yellow')
L0=Button(root,text='0')
Lp=Button(root,text='.')
L1.grid(row=0,column=0)    #按钮放置在0行0列
L2.grid(row=0,column=1)
L3.grid(row=0,column=2)
L4.grid(row=1,column=0)
L5.grid(row=1,column=1)
L6.grid(row=1,column=2)
L7.grid(row=2,column=0)
L8.grid(row=2,column=1)
L9.grid(row=2,column=2)
L0.grid(row=3,column=0,columnspan=2,sticky=E+W)    #跨两列,左右贴紧
Lp.grid(row=3,column=2,sticky=E+W)
root.mainloop()

3.place几何布局管理器

place几何布局管理允许指定组件的大小与位置。place的优点是可以精确控制组件的位置,不足之处是改变窗口大小时,子组件不能随之灵活改变。

place()方法可以提供如下表所示的参数选项,可以直接给参数选项赋值加以修改。

选项 描述 取值范围
x,y 将组件放到指定位置的绝对坐标 从0开始的整数
relx,rely 将组件放到指定位置的相对坐标 取值范围0~1.0
height,width 高度和宽度,单位为像素  
anchor 对齐方式,对应于东南西北以及四个角 'n'/'s'/'e'/'w'/'nw'/'sw'/'se'/'ne'/'center'(默认值)
from tkinter import *
root=Tk()
root.title("登录")
root['width']=200;root['height']=80
Label(root,text='用户名',width=6).place(x=1,y=1)#绝对坐标(1,1)
Entry(root,width=20).place(x=45,y=1)
Label(root,text='密码',width=6).place(x=1,y=20)
Entry(root,width=20,show='*').place(x=45,y=20)
Button(root,text='登录',width=8).place(x=40,y=40)
Button(root,text='取消',width=8).place(x=110,y=40)
root.mainloop()

7.2 常用Tkinter组件的使用

7.2.1 Tkinter组件

常用的Tkinter控件如下表所示:

控件 描述
Button 按钮控件,在程序中显示按钮
Canvas 画布控件,显示图形元素,如线条或文本
Checkbutton 多选框控件,用于在程序中提供多项选择框
Entry 输入控件,用于显示简单的文本内容
Frame 框架控件,在屏幕上显示一个矩形区域,多用来作为容器
Label 标签控件,可以显示文本和位图
Listbox 列表框控件,是用来显示一个字符串列表
Menubutton 菜单按钮控件,用于显示菜单选项
Menu 菜单控件,显示菜单栏、下拉菜单和弹出菜单
Message

消息控件,用来显示多行文本,与label比较类似

Radiobutton 单选按钮控件,显示一个单选的按钮状态
Scale 范围控件,显示一个数值刻度,为输出限定范围的数字区间
Scrollbar 滚动条控件,当内容超过可视化区域时使用,如列表框
Text 文本控件,用于显示多行文本
Toplevel 容器控件,用来提供一个单独的对话框,和Frame比较类似
Spinbox 输入控件,与Entry类似,但是可以指定输入范围值
PanedWindow 窗口布局管理控件,可以包含一个或者多个子控件
LabelFrame 简单的容器控件,常用于复杂的窗口布局
tkMessageBox 用于显示应用程序的消息框

7.2.2 标准属性

属性 描述
dimension 控件大小
color 控件颜色
font 控件字体
anchor 锚点(内容停靠位置),对应于东西南北以及4个角
relief 控件样式
bitmap 位图,内置位图包括:error、gray75、gray50、gray25、gray12、info、questhead、hourglass、questtion和warning,自定义位图为.xbm格式文件
cursor 光标
text 显示文本内容
state 设置组件状态,正常(normal)、激活(active)、禁用(disabled)

可以通过下列方式设置组件属性:

button1=Button(root,text="确定")    #按钮组件的构造函数
button1.config(text="确定")    #组件对象的config()方法的命名函数
button1["text"]="确定"    #组件对象的属性赋值

7.2.3 Label标签组件

属性 说明
width 宽度
height 高度
compound

指定文本与图像如何在Label上显示,默认为None。当指定imag/bitmap时,文本(text)将被覆盖,只显示图像。可以使用的值如下:

left:图像居左

right:图像居右

top:图像居上

bottom:图像居下

center:文字覆盖在图像上

wraplength 指定多少单位后开始换行,用于多行显示文本
justify 指定多行的对齐方式,可以使用的值为LEFT(左对齐)或RIGHT(右对齐)
anchor 指定文本(Text)或图像(Bitmap/Image)在Label中的显示位置
image和bm 显示自定义图片如.png,.gif
bitmap 显示内置的位图
from tkinter import *
win=Tk()
win.title("我的窗口")
lab1=Label(win,text='你好',anchor='nw')
lab1.pack()
lab2=Label(win,bitmap='question')    #创建显示疑问图标的组件
lab2.pack()    #显示Label组件
#显示自选的图片
bm=PhotoImage(file=r'd:\扩容盘\某人的黑照\吴强的头.gif')
lab3=Label(win,image=bm)
lab3.bm=bm
lab3.pack()
win.mainloop()

7.2.4 Button按钮组件

属性 功能描述
text 显示文本内容
command 指定Button的事件处理函数
compound 指定文本与图像的位置关系
bitmap 指定位图
focus_set 设置当前程序得到的焦点
master 代表了父窗口
bg 设置背景颜色
fg 设置前景颜色
font 设置字体大小
height 设置显示高度,如果未设置此项,其大小适应内容标签
relief 指定外观装饰边界附件的标签,默认是平的,可以设置的参数:flat/groove/raised/ridge/solid/sunken
width 设置显示宽度,如果未设置此项,其大小以适应内容标签
wraplength 将此选项设置为所需的数量限制每行的字符,数默认为0
state 设置组件状态,正常(normal)、激活(active)、禁用(disabled)
anchor 设置Button文本在控件上的显示位置
bd 设置Button的边框大小,bd(bordwidth)默认为1或2个像素
textvariable 设置Button可变的文本内容对应的变量
flash() 按钮在正常颜色和激活颜色之间闪烁几次,disabled状态无效
invoke() 调用按钮的command指定的回调函数
from tkinter import *
from tkinter.messagebox import *
root=Tk()
root.title("Button Test")
def callback():
    showinfo("Python command","人生苦短,我用Python")
#创建4个Button按钮、并设置width,height,relief,bg,bd,fg,state,bitmap,
#command,anchor
Button(root,text="外观装饰边界附近的标签",width=19,relief=GROOVE,bg='red').pack()
Button(root,text="设置按钮状态",width=21,state=DISABLED).pack()
Button(root,text="设置bitmap放到按钮左边位置",compound="left",bitmap="error").pack()
Button(root,text="设置command事件调用命令",fg="blue",bd=2,width=28,command=callback).pack()
Button(root,text="设置高度宽度以及文字显示位置",anchor="sw",width=30,height=2).pack()
root.mainloop()

如果想获取文件的所有属性,可通过如下命令列举:

from tkinter import *
root=Tk()
button1=Button(root,text="确定")
print(button1.keys())    #keys()方法列举组件的所有属性

7.2.5 单行文本框(Entry)和多行文本框(Text)

1.创建和显示Entry对象

#创建Entry对象的基本方法:
Entry对象=Entry (Windows窗口对象)
#显示Entry对象的方法:
Entry对象.pack()

2.获取Entry组件的内容

get()方法用于获取Entry当行文本框输入的内容

3.Entry的常用属性

(1)show:如果设置为字符“*”,则输入文本框内显示为“*”,用于密码输入。

(2)insertbackground:插入光标的颜色,默认为黑色。

(3)selectbackground和selectforeground:选中文本的背景色与前景色

(4)width:组件的宽度(所占字符个数)

(5)fg:字体前景颜色

(6)bg:背景颜色

(7)state:设置组件状态,默认为normal,可设置为disabled禁用组件,readonly只读。

#摄氏度转华氏度
import tkinter as tk
def btnHelloClicked():
    cd=float(entryCd.get())    #获取文本框输入的内容,并转换成浮点数
    labelHello.config(text="%.2f C=%.2f F"%(cd,cd*1.8+32))
root=tk.Tk()
root.title("Entry Test")
labelHello=tk.Label(root,text="转换℃to℉...",height=5,width=20,fg="blue")
labelHello.pack()
entryCd=tk.Entry(root)    #Entry组件
entryCd.pack()
btnCa1=tk.Button(root,text="转换温度",command=btnHelloClicked)    #按钮
btnCa1.pack()
root.mainloop

设置或者获取Entry组件的内容也可以使用StringVar()对象来完成。

s=StringVar()    #一个StringVar()对象
s.set("大家好,这是测试")    #设置文本内容
entryCd=Entry(root,textvariable=s)    #Entry组件显示“大家好,这是测试”
print(s.get())    #打印出“大家好,这是测试”

同样,Python提供输入多行文本框Text,用于输入多行内容和显示文本。使用方法类似Entry,请读者参考Tkinter手册。

7.2.6 Listbox列表框组件

1.创建和显示Listbox对象

#创建和显示Listbox的基本方法:
Listbox对象=Listbox(Tkinter Windows窗口对象)
#显示Listbox对象的方法:
Listbox对象.pack()

2.插入文本项

可以使用insert()方法向列表框组件中插入文本项。方法如下:

Listbox对象.insert(index,item)

其中,index是插入文本项的位置,如果在尾部插入文本项,则可以使用END;如果在当前选中处插入文本项,则可以使用ACTIVE。item是要插入的文本项。

3.返回选中项索引

Listbox对象.curselection()

返回当前选中项目的索引,结果为元组。

4.删除文本项

Listbox对象.delete(first,last)

删除指定范围(first,last)的项目,不指定last时,删除一个项目

5.获取项目内容

Listbox对象.get(first,last)

返回指定范围(first,last)的项目,不指定last时,返回一个项目

6.获取项目个数

Listbox对象.size()

7.获取Listbox内容

需要使用listvariable属性为Listbox对象指定一个对应的变量。例如:

m=StringVar()
listb=Listbox(root,listvariable=m)
list.pack()
root.mainloop()

指定后就可以使用m.get()方法获取Listbox对象中的内容。

注意:如果允许用户选择多个项目,需要将Listbox对象的selectmode属性设置为MULIPLE表示多选,而设置为SINGLE表示单选。

#Tkinter创建一个获取Listbox组件内容的程序
from tkinter import *
root=Tk()
m=StringVar()
def callbutton1():
    print(m.get())
def callbutton2():
    for i in lb.curselection():    #返回选中项索引形成的元组
        print(lb.get(i))
root.title("使用Listbox组件的例子")    #设置窗口标题
lb=Listbox(root,listvariable=m)    #将一字符串m与Listbox的值绑定
for item in ['北京','天津','上海']:
    lb.insert(END,item)
lb.pack()
b1=Button(root,text='获取Listbox的所有内容',command=callbutton1,width=20)
b1.pack()
b2=Button(root,text='获取Listbox的选中内容',command=callbutton2,width=20)
b2.pack()
root.mainloop()

单击“获取Listbox的所有内容”按钮,则输出:('北京','天津','上海')

选中上海后,单击“获取Listbox的选中内容”按钮则输出:上海。

#从一个列表框选择内容添加到另一个列表框组件的GUI程序
from tkinter import *
root=Tk()
def callbutton1():
    for i in listb.curselection():
        listb2.insert(0,listb.get(i))    #添加到右侧列表框
def callbutton2():
    for i in listb2.curselection():
        listb2.delete(i)
li=['C','Python','php','html','SQL','java']
listb=Listbox(root)
listb2=Listbox(root)
for item in li:
    listb.insert(0,item)
listb.grid(row=0,column=0,rowspan=2)    #将列表框组件放置到窗口对象中
b1=Button(root,text='添加>>',command=callbutton1,width=20)
b2=Button(root,text='删除<<',command=callbutton2,width=20)
b1.grid(row=0,column=1,rowspan=2)
b2.grid(row=1,column=1,rowspan=2)
listb2.grid(row=0,column=2,rowspan=2)
root.mainloop()

7.2.7 单选按钮(Radiobutton)和复选框(Checkbutton)

1.创建和显示Radiobutton对象

#创建Radiobutton对象的基本方法:
Radiobutton对象=Radiobutton (Windows窗口对象,text=Radiobutton组件显示的文本)
#显示Radiobutton对象的方法:
Radiobutton对象.pack()

2.Radiobutton组件的常用属性

(1)variable:单选按钮索引变量,通过变量的值确定哪个单选按钮被选中。一组单选按钮使用同一个索引变量。

(2)value:单选按钮选中时变量的值

(3)command:单选按钮选中时执行的命令(函数)。

3.Radiobutton组件的方法

(1)deselect():取消选择

(2)select():选择

(3)invoke():调用单选按钮(command)指定的回调函数

4.创建和显示Checkbutton对象

#创建Checkbutton对象的基本方法:
Checkbutton对象=Checkbutton(Tkinter Windows窗口对象,text=Checkbutton
组件显示的文本,command=单击Checkbutton按钮所调用的函数)
#显示Checkbutton对象的方法:
Checkbutton对象.pack()

5.Checkbutton组件的常用属性

(1)variable:复选框索引变量,通过变量的值确定哪些复选框被选中。每个复选框使用不同的变量,使复选框之间相互独立。

(2)onvalue:复选框选中(有效)时变量的值

(3)offvalue:复选框未选择(无效)时变量的值

(4)command:复选框选中时执行的命令(函数)

6.获取Checkbutton的状态

为了获取Checkbutton组件是否被选中,需要使用variable属性为Checkbutton组件指定一个对应变量。

c=tkinter.IntVar()
c.set(2)
check=tkinter.Checkbutton(root,text='喜欢',variable=c,onvalue=1,
                          offvalue=2)
check.pack()
#使用单选按钮(Radiobutton)组件选择国家的程序
import tkinter
root=tkinter.Tk()
r=tkinter.StringVar()
r.set('1')
radio=tkinter.Radiobutton(root,variable=r,value='1',text='中国')
radio.pack()
radio=tkinter.Radiobutton(root,variable=r,value='2',text='美国')
radio.pack()       
radio=tkinter.Radiobutton(root,variable=r,value='3',text='日本')
radio.pack()
radio=tkinter.Radiobutton(root,variable=r,value='4',text='加拿大')
radio.pack()
radio=tkinter.Radiobutton(root,variable=r,value='5',text='韩国')
radio.pack()
root.mainloop()
print(r.get())
import tkinter as tk
def colorChecked():
    label_1.config(fg=color.get())
def typeChecked():
    textType=typeBlod.get()+typeItalic.get()
    if textType==1:
        label_1.config(font=("Arial",12,"bold"))
    elif textType==2:
        label_1.config(font=("Arial",12,"italic"))
    elif textType==3:
        label_1.config(font=("Arial",12,"bold italic"))
    else:
        label_1.config(font=("Arial",12))
root=tk.Tk()
root.title("Radio & Check Test")
label_1=tk.Label(root,text="Check the format of text.",height=3,font=("Arial",12))
label_1.config(fg="blue")
label_1.pack()
color=tk.StringVar()    #3种颜色Radiobutton定义了同样的变量color
color.set("blue")
tk.Radiobutton(root,text="红色",variable=color,value="red",command=colorChecked).pack(side=tk.LEFT)
tk.Radiobutton(root,text="蓝色",variable=color,value="blue",command=colorChecked).pack(side=tk.LEFT)
tk.Radiobutton(root,text="绿色",variable=color,value="green",command=colorChecked).pack(side=tk.LEFT)
#IntVar()是对整数类型的包装,StringVar是对字符串类型的包装
typeBlod=tk.IntVar()    #定义typeBlod变量表示文字是否为粗体
typeItalic=tk.IntVar()    #定义typeItalic变量表示文字是否为斜体
tk.Checkbutton(root,text="粗体",variable=typeBlod,onvalue=1,offvalue=0,command=typeChecked).pack(side=tk.LEFT)
tk.Checkbutton(root,text="斜体",variable=typeBlod,onvalue=2,offvalue=0,command=typeChecked).pack(side=tk.LEFT)

7.2.8 菜单组件(Menu)

图形用户界面应用程序包括2种类型的菜单:

(1)主菜单:提供窗体的菜单系统。通过单击可下拉出子菜单。

(2)上下文菜单(也称为快捷菜单):通过右击某个对象弹出的菜单。

1.创建和显示Menu对象

#创建Menu对象的基本方法:
Menu 对象=Menu(Windows窗口对象)
#将Menu对象显示在窗口中的方法:
Windows窗口对象['menu']=Menu对象
Windows窗口对象.mainloop()
from tkinter import *
root=Tk()
m=Menu(root)
for item in ['文件','编辑','视图']:
    m.add_command(label=item)
root['menu']=m
root.mainloop()

2.添加下拉菜单

下面的语句将Menu对象2设置为Menu对象1的下拉菜单。

Menu对象1.add_cascade(label=菜单文本,menu=Menu对象2)

在创建Menu对象2的时候也要指定它是Menu对象1的子菜单。方法如下:

Menu对象2=Menu(Menu对象1)
#给“文件”、“编辑”添加下拉菜单
from tkinter import *
root=Tk()
m1=Menu(root)
filemenu=Menu(m1)
editmenu=Menu(m1)
for item in ['打开','关闭','退出']:
    filemenu.add_command(label=item)
for item in ['复制','剪切','粘贴']:
    editmenu.add_command(label=item)
m1.add_cascade(label='文件',menu=filemenu)
m1.add_cascade(label='编辑',menu=editmenu)
root['menu']=m1
root.mainloop()

3.在菜单中添加复选框

菜单对象.add_checkbutton(label=复选框的显示文本,command=菜单命令函数,variable=与复选框绑定的变量)
#在菜单中添加复选框“自动保存”。
from tkinter import *
def hello():
    print(v.get())
root=Tk()
v=StringVar()
m1=Menu(root)
filemenu=Menu(m1)
editmenu=Menu(m1)
for item in ['打开','关闭','退出']:
    filemenu.add_command(label=item)
for item in ['复制','剪切','粘贴']:
    editmenu.add_command(label=item)
m1.add_cascade(label='文件',menu=filemenu)
m1.add_cascade(label='编辑',menu=editmenu)
filemenu.add_checkbutton(label='自动保存',command=hello,variable=v)
root['menu']=m1
root.mainloop()

4.在菜单中的当前位置添加分隔符

菜单对象.add_separator()

from tkinter import *
def hello():
    print("I'm a child menu")
root=Tk()
m=Menu(root)
filemenu=Menu(m)
filemenu.add_command(label='打开',command=hello)
filemenu.add_command(label='关闭',command=hello)
filemenu.add_separator()
filemenu.add_command(label='退出',command=hello)
m.add_cascade(label='文件',menu=filemenu)
root['menu']=m
root.mainloop()

5.创建上下文菜单

创建上下文菜单一般遵循下列步骤:

(1)创建菜单。

menubar=Menu(root)
menubar.add_command(label='剪切',command=hello1)
menubar.add_command(labei='复制',command=hello2)
menubar.add_command(label='粘贴',command=hello3)

(2)绑定鼠标右击事件,并在事件处理函数中弹出菜单。

def popup(event)#事件处理函数
    menubar.post(event.x_root,event.y_root)    #鼠标右键位置显示菜单
root.bind('',popup)    #绑定事件
from tkinter import *
def popup(event):
    menubar.post(event.x_root,event.y_root)    #在鼠标右键位置显示菜单
def hello1():
    print("我是剪切命令")
def hello2():
    print("我是复制命令")
def hello3():
    print("我是粘贴命令")
root=Tk()
root.geometry("300x150")
menubar=Menu(root)
menubar.add_command(label='剪切',command=hello1)
menubar.add_command(label='复制',command=hello2)
menubar.add_command(label='粘贴',command=hello3)
#创建Entry组件界面
s=StringVar()
s.set("大家好,这是测试上下文次菜单")
entryCd=Entry(root,textvariable=s)
entryCd.pack()
root.bind('',popup)
root.mainloop()

7.2.9 对话框

1.文件对话框

模块tkinter的子模块filedialog包含用于打开文件对话框的函数askopenfilename()。文件对话框供用户选择某文件夹下的文件,格式如下:

askopenfilename(title='标题',filetypes=[('所有文件','.*'),('文本文件','.txt')])

(1)filetypes:文件过滤器,可以筛选某种格式的文件

(2)title:设置打开文件对话框的标题

同时还有文件保存对话框函数asksaveasfilename()。格式如下:

asksaveasfilename(title='标题',initialdir='d:\myword',initialfile='hello.py')

(1)initialdir:默认文件路径,如'd:\mywork'。

(2)initialfile:默认保存的文件名,如'hello.py'。

from tkinter import *
from tkinter.filedialog import *
def openfile():
    #显示打开文件对话框,返回选中文件名及路径
    r=askopenfilename(title='打开文件',filetypes=[('Python','*.py *.pyw'),('All Files','*')])
def savefile():
    #显示保存文件对话框
    r=asksaveasfilename(title='保存文件',initialdir='d:\mywork',
                            initialfile='hello.py')
root=Tk()
root.title('打开文件对话框示例')
root.geometry("300x150")
btn1=Button(root,text='File Open',command=openfile)
btn2=Button(root,text='File Save',command=savefile) 
btn1.pack(side='left')
btn2.pack(side='left')
root.mainloop()

2.颜色对话框

模块tkinter的子模块colorchoose包含用于打开颜色对话框的函数askcolor()。颜色对话框供用户选择某颜色。

from tkinter import *
from tkinter.colorchooser import *
root=Tk()
print(askcolor())
root.mainloop()

3.简单对话框

(1)模块tkinter的子模块simpledialog中,包含用于打开输入对话框的函数。

(2)askfloat(title,prompt,选项):打开输入对话框,输入并返回浮点数。

(3)askinteger(title,prompt,选项):打开输入对话框,输入并返回整数。

askstring(title,prompt,选项):打开对话框,输入并返回字符串

其中,title为窗口标题,prompt为提示文本信息;“选项”是指各种选项,包括initialvalue(初始值)、minvalue(最小值)和maxvalue(最大值)。

import tkinter
from tkinter import simpledialog
def inputStr():
    r=simpledialog.askstring('Python Tkinter','Input String',
                             initialvalue='Python Tkinter')
    print(r)
def inputInt():
    r=simpledialog.askinteger('Python Tkinter','Input Integer')
    print(r)
def inputFloat():
    r=simpledialog.askfloat('Python Tkinter','Input Float')
    print(r)
root=tkinter.Tk()
btn1=tkinter.Button(root,text='Input String',command=inputStr)
btn2=tkinter.Button(root,text='Input Integer',command=inputInt)
btn3=tkinter.Button(root,text='Input Float',command=inputFloat)
btn1.pack(side='left')
btn2.pack(side='left')
btn3.pack(side='left')
root.mainloop()

7.2.10 消息窗口(消息框)

消息窗口(meaasgebox)用于弹出提示框向用户进行告警,或让用户选择下一步如何操作。

import tkinter as tk
from tkinter import messagebox as msgbox
def btn1_clicked():
    msgbox.showinfo("Info","Showinfo.test.")
def btn2_clicked():
    msgbox.showinfo("Warning","Showwarning.test.")
def btn3_clicked():
    msgbox.showerror("Error","Showerror test.")
def btn4_clicked():
    msgbox.askquestion("Question","Askquestion test.")
def btn5_clicked():
    msgbox.askokcancel("OkCancel","Askokcancel.test.")
def btn6_clicked():
    msgbox.askyesno("YesNo","Askyesno test.")
def btn7_clicked():
    msgbox.askretrycancel("Retry","Askretrycancel test.")
root=tk.Tk()
root.title("MsgBox Test")
btn1=tk.Button(root,text="showinfo",command=btn1_clicked)
btn1.pack(fill=tk.X)
btn2=tk.Button(root,text="showwarning",command=btn2_clicked)
btn2.pack(fill=tk.X)
btn3=tk.Button(root,text="showerror",command=btn3_clicked)
btn3.pack(fill=tk.X)
btn4=tk.Button(root,text="askquestion",command=btn4_clicked)
btn4.pack(fill=tk.X)
btn5=tk.Button(root,text="askokcancel",command=btn5_clicked)
btn5.pack(fill=tk.X)
btn6=tk.Button(root,text="askyesno",command=btn6_clicked)
btn6.pack(fill=tk.X)
btn7=tk.Button(root,text="askretrycancel",command=btn7_clicked)
btn7.pack(fill=tk.X)
root.mainloop()

7.2.11 Frame框架组件

1.创建和显示Frame对象

#创建Frame对象的基本方法:
Frame 对象=Frame(窗口对象,height=高度,width=宽度,bg=背景色,...)
#创建第1个Frame组件,其高为100,宽为400,背景色为绿色
f1=Frame(root,height=100,width=400,bg='green')
#显示Frame对象的方法:
Frame对象.pack()

2.向Frame组件中添加组件

在创建组件时可以指定其容器为Frame组件。

Label(Frame对象,text='Hello').pack()    #向Frame组件添加一个Label组件

3.LabelFrame组件

LabelFrame组件是有标题的Frame组件,可以使用text属性设置LabelFrame组件的标题:

LabelFrame(窗口对象,height=高度,width=宽度,text=标题).pack()
from tkinter import *
root=Tk()
root.title("使用Frame组件的例子")
f1=Frame(root)
f1.pack()
f2=Frame(root)
f2.pack()
f3=LabelFrame(root,text='第3个Frame')    #第3个LabelFrame组价,放置在窗口底部
f3.pack(side=BOTTOM)
redbutton=Button(f1,text='Red',fg="red")
redbutton.pack(side=LEFT)
brownbutton=Button(f1,text="Brown",fg="brown")
brownbutton.pack(side=LEFT)
bluebutton=Button(f1,text="Blue",fg="blue")
bluebutton.pack(side=LEFT)
blackbutton=Button(f2,text="Black",fg="black")
blackbutton.pack()
greenbutton=Button(f3,text="Green",fg="Green")
greenbutton.pack()
root.mainloop()

此时,通过Frame框架把5个按钮分成3个区域:第一个区域3个按钮;第二个区域1个按钮;第三个区域1个按钮

4.刷新Frame

用Python做GUI图形界面,可以使用after()方法每隔几秒刷新GUI图形界面。

#实现计数器效果,并且文字背景色不断改变
from tkinter import *
colors=('red','orange','yellow','green','blue','purple')
root=Tk()
f=Frame(root,height=200,width=200)
f.color=0
f['bg']=colors[f.color]
lab1=Label(f,text='0')
lab1.pack()
def foo():
    f.color=(f.color+1)%(len(colors))    #取余
    lab1['bg']=colors[f.color]
    lab1['text']=str(int(lab1['text'])+1)
    f.after(800,foo)    #隔500ms执行foo函数刷新屏幕
f.pack()
f.after(500,foo)
root.mainloop()
from tkinter import *
root=Tk()
f=Frame(root,height=200,width=200)
lab1=Label(f,text='欢迎参加中原工学院')
x=0
def foo():
    global x    #声明变量的作用是全局作用域
    x+=10
    if x>200:
        x=0
    lab1.place(x=x,y=0)
    f.after(500,foo)
f.pack()
f.after(500,foo)
root.mainloop()

7.2.12 Scrollbar滚动条组件

Scrollbar组件是滚动条组件,Scrollbar组件用于滚动一些组件的可见范围,根据方向可分为垂直滚动条和水平滚动条。

在某个组件上添加垂直滚动条,需要2个步骤:

(1)设置该组件的yscrollbarcommand选项为Scrollbar组件的set()方法。

(2)设置Scrollbar组件的command选项为该组件的yview()方法。

from tkinter import *
def print_item(event):   #鼠标松开事件打印出当前选中项内容
    print(mylist.get(mylist.curselection()))
root=Tk()
mylist=Listbox(root)    #创建列表框
mylist.bind('',print_item)
for line in range(100):
    mylist.insert(END,"This is line number"+str(line))
mylist.pack(side=LEFT,fill=BOTH)
scrollbar=Scrollbar(root)
scrollbar.pack(side=RIGHT,fill=Y)
scrollbar.config(command=mylist.yview)
mylist.configure(yscrollcommand=scrollbar.set)
root.mainloop()

同样,也可以添加一个水平方向的Scrollbar,只需要设置好xscrollcommand和xview即可。

7.3 图形绘制

7.3.1 Canvas画布组件

创建Canvas对象:

Canvas对象=Canvas(窗口对象,选项,...)

Canvas画布常用选项如下表所示:

选项 说明
bd 指定画布的边框宽度,单位是像素
bg 指定画布的背景颜色
confine 指定画布在滚动区域外是否可以滚动。默认为True,表示不能滚动
cursor 指定画布中的鼠标指针,例如arrow、circle、dot
height 指定画布的高度
highlightcolor 选中画布时的背景色
relief 指定画布的边框样式,可选值包括SUNKEN、RAISED、GROOVE、RIDGE
scrollregion 指定画布的滚动区域的元组(w,n,e,s)

显示Canvas对象的方法如下:

Canvas对象.pack()
from tkinter import *
root=Tk()
cv=Canvas(root,bg='white',width=300,height=120)
cv.create_line(10,10,100,80,width=2,dash=7)
cv.pack()
root.mainloop()

7.3.2 Canvas上的图形对象

1.绘制图形对象

(1)create_arc():绘制圆弧

(2)create_line():绘制直线

(3)create_bitmap():绘制位图

(4)create_image():绘制位图图像

(5)create_oval():绘制椭圆

(6)create_polygon():绘制多边形

(7)create_window():绘制子窗口

(8)create_text():创建一个文字对象

Canvas上每个绘制对象都有一个标识id(整数),使用绘制函数创建绘制对象时,返回绘制对象id。

在创建图形对象时可以使用属性tags设置图形对象的标记(tag)。例如:

rt=cv.create_rectangle(10,10,110,110,tags='r1')

上面的语句指定矩形对象rt具有一个标记r1。

也可以同时设置多个标记(tag)。例如:

rt=cv.create_rectangle(10,10,110,110,tags=('r1','r2','r3'))

上面的语句指定矩形对象rt具有3个标记r1、r2、r3。

指定标记后,使用find_withtag()方法可以获取到指定tag的图形对象,然后设置图形对象的属性。

Canvas对象.find_withtag(tag名)

使用itemconfig()方法可以设置图形对象的属性。

Canvas对象.itemconfig(图形对象,属性1=值1,属性2=值2...)
from tkinter import *
root=Tk()
#创建一个Canvas,设置其背景色为白色
cv=Canvas(root,bg='white',width=200,height=200)
#使用tags指定给第一个矩形指定3个tag
rt=cv.create_rectangle(10,10,110,110,tags=('r1','r2','r3'))
cv.pack()
cv.create_rectangle(20,20,80,80,tags='r3')    #使用tags给第2个矩形指定1个tag
#将所有与tag('r3')绑定的item边框颜色设置为蓝色
for item in cv.find_withtag('r3'):
    cv.itemconfig(item,outline='blue')
root.mainloop()

2.绘制圆弧

Canvas对象.create_arc(弧外框矩形左上角的x坐标,弧外框矩形左上角的y坐标,弧外框矩形右下角的x坐标,弧外框矩形右下角的y坐标,选项,...)

创建圆弧常用选项:outline——指定圆弧边框颜色;fill——指定填充颜色;width——指定圆弧边框的宽度;start——代表起始角度;extent——代表指定角度偏移量,而不是终止角度

from tkinter import *
root=Tk()
#创建一个Canvas,设置其背景色为白色
cv=Canvas(root,bg='white')
cv.create_arc((10,10,110,110))    #使用默认参数创建一个圆弧,结果为90°的扇形
d={1:PIESLICE,2:CHORD,3:ARC}
for i in d:
    #使用3种样式,分别创建了扇形、弓形和弧形
    cv.create_arc((10,10+60*i,110,110+60*i),style=d[i])
    print(i,d[i])
#使用start/extent指定圆弧起始角度与偏移角度
cv.create_arc(
    (150,150,250,250),
    start=10,
    extent=120
    )
cv.pack()
root.mainloop()

3.绘制线条

create_line()方法具体语法:

line=canvas.create_line(x0,y0,x1,y1,...,xn,yn,选项)

常用选项:width——线段宽度;arrow——是否适用箭头(没有箭头none,起点有箭头first,终点有箭头last,两端有箭头both);fill——线段颜色;dash——线段为虚线(其整数值决定虚线的样式)

from tkinter import *
root=Tk()
cv=Canvas(root,bg='white',width=200,height=100)
cv.create_line(10,10,100,10,arrow='none')
cv.create_line(10,20,100,20,arrow='first')
cv.create_line(10,30,100,30,arrow='last')
cv.create_line(10,40,100,40,arrow='both')
cv.create_line(10,50,100,100,width=3,dash=7)
cv.pack()
root.mainloop()

4.绘制矩形

create_rectangle()方法具体语法:

Canvas对象.create_rectangle(矩形左上角的x坐标,矩形左上角的y坐标,矩形右下角的x坐标,矩形右下角的y坐标,选项,...)

常用选项:outline——边框颜色;fill——填充颜色;width——边框的宽度;dash——边框为虚线;stipple——使用指定自定义画刷填充矩形

from tkinter import *
root=Tk()
#创建一个Canvas,设置其背景色为白色
cv=Canvas(root,bg='white',width=200,height=100)
cv.create_rectangle(10,10,110,110,width=2,fill='red')
#指定矩形的填充色为红色,宽度为2
cv.create_rectangle(120,20,180,80,outline='green')
#指定矩形的边框为绿色
cv.pack()
root.mainloop()

5.绘制多边形

create_polygon()方法具体语法:

Canvas对象.create_polygon(顶点1的x坐标,顶点1的y坐标,顶点2的x坐标,顶点2的y坐标,...,顶点n的x坐标,顶点n的y坐标,...,顶点n的x坐标,顶点n的y坐标,选项,...)

常用选项:outline——边框颜色;fill——填充颜色;width——边框的宽度;smooth——平滑程度(0表示边是折线,1表示边是平滑曲线)

#创建三角形、正方形、对顶三角形
from tkinter import *
root=Tk()
cv=Canvas(root,bg='white',width=300,height=100)
cv.create_polygon(35,10,10,60,60,60,outline='blue',fill='red',width=2)
cv.create_polygon(70,10,120,10,120,60,outline='blue',fill='white',width=2)
cv.create_polygon(130,10,180,10,180,60,130,60,width=4)
cv.create_polygon(190,10,240,10,190,60,240,60,width=1)
cv.pack()
root.mainloop()

6.绘制椭圆

create_oval()方法具体语法:

Canvas对象.create_oval(包裹椭圆的矩形左上角x坐标,包裹椭圆的矩形左上角y坐标,包裹椭圆的矩形右下角x坐标,包裹椭圆的矩形右下角y坐标,选项,...)

常用选项:outline——边框颜色;fill——填充颜色;width——边框的宽度;如果包裹椭圆的矩形是正方形,则绘制一个圆形

7.绘制文字

create_text()方法具体语法:

文字对象=Canvas对象.create_text((文本左上角的x坐标,文本左上角的y坐标),选项,...)

常用选项:text——文本对象的文本内容;fill——文字颜色;anchor——控制文字对象的位置;justify——文字对象中文本的对齐方式('left'表示左对齐,'right'表示右对齐,'center'表示居中对齐)

from tkinter import *
root=Tk()
cv=Canvas(root,bg='white',width=300,height=100)
cv.create_text((10,10),text='Hello Python',fill='red',anchor='nw')
cv.create_text((200,50),text='你好,Python',fill='blue',anchor='se')
cv.pack()
root.mainloop()

select_from()方法用于指定选中文本的起始位置,select_to()方法用于指定结束位置。

Canvas对象.select_from(文字对象,选中文本的起始位置)
Canvas对象.select_to(文字对象,选中文本的结束位置)
from tkinter import *
root=Tk()
cv=Canvas(root,bg='white',width=200,height=100)
txt=cv.create_text((10,10),text='中原工学院计算机学院',fill='red',anchor='nw')
#设置文本的起始位置
cv.select_from(txt,5)
#设置文本的结束位置
cv.select_to(txt,9)
cv.pack()
root.mainloop()

8.绘制位图和图像

(1)绘制位图:

Canvas对象.create_bitmap((x坐标,y坐标),bitmap=位图字符串,选项,...)

(x坐标,y坐标)是位图放置的中心坐标;常用选项有bitmap、activebitmap和disablebitmap,分别用于指定正常、活动、禁用状态显示的位图

(2)绘制图像:

Canvas对象.create_image((x坐标,y坐标),image=图像文件对象,选项,...)

(x坐标,y坐标)是位图放置的中心坐标;常用选项有image、activeimage和disableimage,分别用于指定正常、活动、禁用状态显示的图像

PhotoImage()函数用于获取图像文件对象:

img1=PhotoImage(file=图像文件)

Python支持的图像文件格式一般为.png和.gif。

from tkinter import *
root=Tk()
cv=Canvas(root)
img1=PhotoImage(file='C:\\aa.png')    #笑脸
img2=PhotoImage(file='C:\\2.gif')    #方块A
img3=PhotoImage(file='C:\\3.gif')    #梅花A
cv.create_image((100,100),image=img1)    #绘制笑脸
cv.create_image((200,100),image=img2)    #绘制方块A
cv.create_image((300,100),image=img3)    #绘制梅花A
d={1:'erroe',2:'info',3:'question',4:'hourglass',5:'questhead',
   6:'warning',7:'gray12',8:'gray25',9:'gray50',10:'gray75'}#字典
#以下遍历字典绘制Python内置的位图
for i in d:
    cv.create_bitmap((20*i,20),bitmap=d[i])
cv.pack()
root.mainloop()

9.修改图形对象的坐标

使用coords()方法可以修改图形对象的坐标。

Canvas对象.coords(图形对象,(图形左上角的x坐标,图形左上角的y坐标,图形右下角的x坐标,图形右下角的y坐标))

因为可以同时修改图形对象左上角的坐标和右下角的坐标,所以可以缩放图形对象。如果图像对象是图像文件,则只能指定图像中心点坐标,故不能缩放图像

from tkinter import *
root=Tk()
cv=Canvas(root)
img1=PhotoImage(file='C:\\aa.png')    #笑脸
img2=PhotoImage(file='C:\\2.gif')    #方块A
img3=PhotoImage(file='C:\\3.gif')    #梅花A
rt1=cv.create_image((100,100),image=img1)    #绘制笑脸
rt2=cv.create_image((200,100),image=img2)    #绘制方块A
rt3=cv.create_image((300,100),image=img3)    #绘制梅花A
#重新设置方块A(rt2对象)的坐标
cv.coords(rt2,(200,50))
rt4=cv.create_rectangle(20,140,110,220,outline='red',fill='green')
cv.coords(rt4,(100,150,300,200))
cv.pack()
root.mainloop()

10.移动指定图形对象

Canvas对象.move(图形对象,x坐标偏移量,y坐标偏移量)
from tkinter import *
def callback():
    cv.move(rt1,150,150)
root=Tk()
root.title('移动“帅”棋子')
cv=Canvas(root,bg='white',width=260,height=220)
img1=PhotoImage(file='红帅.png')
cv.create_rectangle(40,40,190,190,outline='red',fill='green')
rt1=cv.create_image((40,40),image=img1)
cv.pack()
button1=Button(root,text="移动棋子",command=callback,fg='red')
button1.pack()
root.mainloop()

11.删除图形对象

Canvas对象.delete(图形对象)

12.缩放图形对象

Canvas对象.scale(图形对象,x轴偏移量,y轴偏移量,x轴缩放比例,y轴缩放比例)
from tkinter import *
root=Tk()
cv=Canvas(root,bg='white',width=200,height=300)
rt1=cv.create_rectangle(10,10,110,110,outline='red',stipple='gray12',fill='green')
rt2=cv.create_rectangle(10,10,110,110,outline='green',stipple='gray12',fill='red')
cv.scale(rt1,0,0,1,2)
cv.scale(rt2,0,0,0.5,0.5)
cv.pack()
root.mainloop()

7.4 Tkinter字体

7.4.1 通过元组表示字体

通过3个元素的元组,可以表示字体:

(font family,size,modifiers)

第一个是字体名;第二个是字体大小;第三个是包含粗体、斜体、下划线的样式修饰符

from tkinter import *
root=Tk()
for ft in ('Arial',('Courier New',19,'italic'),('Comic Sans MS',),'Fixdsys',('MS Sans Serif',),('MS Serief',),'Symbol','System',('Times New Roman',),'Verdana'):
    Label(root,text='Hello sticky',font=ft).grid()
root.mainloop()

字体中包含有空格的字体名称必须指定为元组类型。

7.4.2 通过Font对象表示字体

ft=tkFont.Font(family="字体名",size,weight,slant,underline,overstrike)

其中,size为字体大小;weight='bold'或'normal','bold'为粗体;slant='italic'或'normal','italic'为斜体;underline=1或0,1为下划线;overstrike=1或0,1为删除线

from tkinter import *
import tkinter.font
root=Tk()
ft=tkinter.font.Font(family='Fixdays',size=20,weight='bold')
Label(root,text='Hello sticky',font=ft).grid()
root.mainloop()

通过tkFont.families()函数可以返回所有可用的字体。

from tkinter import *
import tkinter.font
root=Tk()
print(tkinter.font.families())

7.5 Python事件处理

7.5.1 事件类型

事件类型的通用格式:

<[modifier-]...type[-detail]>

事件类型必须放置于尖括号<>内。type描述了类型,例如键盘按键、鼠标单击;modifier用于组合键定义,例如Control、Alt;detail用于明确定义是哪一个键或按钮的事件,例如1表示鼠标左键、2表示鼠标中键、3表示鼠标右键。例如:

    按下鼠标左键
    按下键盘上的A键
    同时按下了Control、Shift、A三个按键

Python中的事件主要有:键盘事件、鼠标事件、窗体事件。

名称 描述
KeyPress 按下键盘某键时触发,可以在detail部分指定是哪个键
KeyRelease 释放键盘某键时触发,可以在detail部分指定是哪个键
名称 描述
ButtonPress或Button 按下鼠标某键,可以在detail部分指定是哪个键
ButtonRelease 释放鼠标某键,可以在detai部分指定是哪个键
Motion 点中组件的同时拖动组件移动时触发
Enter 当鼠标指针移进某组件时触发
Leave 当鼠标指针移出某组件时触发
MouseWheel 当鼠标滚轮滚动时触发
名称 描述
Visibility 当组件变为可视状态时触发
Unmap 当组件由显示状态变为隐藏状态时触发
Map 当组件由隐藏状态变为显示状态时触发
Express 当组件从原本被其他组件遮盖的状态中暴露出来时触发
FocusIn 组件获得焦点时触发
FocusOut 组件失去焦点时触发
Configure 当改变组件大小时触发,例如拖动窗体边缘
Property 当窗体的属性被删除或改变时触发,属于Tk的核心操作
Destroy 当组件被销毁时触发
Activate 与组件选项中的state项有关,表示组件由不可用转为可用。例如,按钮由disabled(灰色)转为enabled
Deactivate 与组件选项中的state项有关,表示组件由不可用转为可用。例如,按钮由enabled转为disabled(灰色)

modifier组合键定义中常用的修饰符如下表:

修饰符 描述
Alt 当【Alt】键按下
Any

任何按键按下,例如

Control 【Ctrl】键按下
Double 两个事件在短时间内发生,例如双击鼠标左键

Lock

当【Caps Lock】键按下
Shift 当【shift】键按下
Triple 类似于Double,3个事件短时间内发生

可以短格式表示事件,例如:<1>等同于等同于

对于大多数的单字符按键,还可以忽略<>符号,但是空格键和尖括号键不能这样做(正确的表示分别为)。

7.5.2 事件绑定

程序建立一个处理某一事件的事件处理函数,称为绑定。

1.创建组件对象时指定

创建组件对象实例时,可通过其命名参数command指定事件处理函数。例如:

def callback():
    showinfo("Python command","人生苦短,我用Python")
Bu1=Button(root,text="设置command事件调用命令",command=callback)
Bu1.pack()

2.实例绑定

组件对象实例名.bind("<事件类型>",事件处理函数)
canvas.bind("",drawline)

特别的是:drawline后面的圆括号是省略的,Tkinter会将此函数填入相关参数后调用运行,在这里只是声明。

3.标识绑定

将图形与事件绑定可以使用标识绑定函数tag_bind()。预先为图形定义标识tag后,通过标识tag来绑定事件。

from tkinter import *
root=Tk()
def printRect(event):
    print('rectangle左键事件')
def printRect2(event):
    print('rectangle右键事件')
def printLine(event):
    print('Line事件')
cv=Canvas(root,bg='white')
rt1=cv.create_rectangle(
    10,10,110,110,
    width=8,tags='r1')
cv.tag_bind('r1','',printRect)
cv.tag_bind('r1','',printRect2)
cv.create_line(180,70,280,70,width=10,tags='r2')
cv.tag_bind('r2','',printLine)
cv.pack()
root.mainloop()

7.5.3 事件处理函数

1.定义事件处理函数

2.Event事件处理参数属性

参数 说明
.x,.y 鼠标相对于组件对象左上角的坐标
.x_root,.y_root 鼠标相对于屏幕左上角的坐标
.keysym 字符串命名按键,例如Escape,F1...F12,Scroll_Lock,Pause,Insert,Delete,Home,Prior(这个是page up),Next(这个是page down),End,Up,Right,Left,Down,Shift_L,Shift_R,Control_R,Alt_L,Alt_R,Win_L
.keysym_num 数字代码命名按键
.keycode 键码,但是它不能反映事件前缀:Alt、Control、Shift、Lock,并且它不区分大小写按键,即输入a和A是相同的键码
.time 时间
.type 事件类型
.widget 触发事件的对应组件
.char 字符

Event按键详细信息说明如下表所示:

.keysym .keycode .keysym_num 说明
Alt_L 64 65513 左手边的【Alt】键
Alt_R 113 65514 右手边的【Alt】键
BackSpace 22 65288 【Backspace】键
Cancel 110 65387 【Pause Break】键
F1~F11 67~77 65470~65480 功能键【F1~F11】
Print 111 65377 打印屏幕键

触发keyPress键盘事件的例子:

from tkinter import *
def printkey(event):
    print('你按下了:'+event.char)
root=Tk()
entry=Entry(root)
#给输入框绑定按键监听事件为监听任何按键
#监听某键x,如大写的A、回车
entry.bind('',printkey)
entry.pack()
root.mainloop()

获取单击标签(Label)时坐标的鼠标事件例子:

from tkinter import *
def leftClick(event):
    print("x轴坐标:",event.x)
    print("y轴坐标:",event.y)
    print("相对于屏幕左上角x轴坐标:",event.x_root)
    print("相对于屏幕左上角y轴坐标:",event.y_root)
root=Tk()
lab=Label(root,text="hello")
lab.pack()
lab.bind("",leftClick)
root.mainloop()

7.6 图形界面应用案例——开发猜数字游戏

import tkinter as tk
import sys
import random
import re
number=random.randint(0,1024)    #玩家要猜的数字
running=True
num=0    #猜的次数
nmaxn=1024    #提示猜测范围的最大数
nminn=0    #提示猜测范围的最小数

def eBtnClose(event):    #关闭按钮事件函数
    root.destroy()
def eBtnGuess(event):    #猜按钮事件函数
    global nmaxn
    global nminn
    global num
    global running
    if running:
        val_a=int(entry_a.get())    #获取猜的数字并转换成数字
        if val_a==number:
            labelqval("恭喜答对了!")
            num+=1
            running=False
            numGuess()
        elif val_anminn:
                nminn=val_a
                num+=1
                labelqval("小了哦,请输入"+str(nminn)+"到"+str(nmaxn)+"之间任意整数:")
        else:
            if val_a',eBtnGuess)
btnGuess.bind('',eBtnGuess)
btnGuess.pack(side="left")
btnClose=tk.Button(root,text="关闭")
btnClose.bind('',eBtnClose)
btnClose.pack(side="left")
labelqval("请输入0到1024之间的任意整数:")
entry_a.focus_set()    #有时候你进入一个网站,你的鼠标是不是基本上都固定在用户名那个textBox,就是这个意思。

7.7 图形界面应用案例——窗体图形版发牌

from tkinter import *
import random
n=52
def gen_pocker(n):
    x=100
    while(x>100):
        x=x-1
        p1=random.randint(0,n-1)
        p2=random.randint(0,n-1)
        t=pocker[p1]
        pocker[p1]=pocker[p2]
        pocker[p2]=t
    return pocker
pocker=[i for i in range(n)]
pocker=gen_pocker(n)
print(pocker)

(player1,player2,player3,player4)=([],[],[],[])    #4位牌手各自牌的图片列表
(p1,p2,p3,p4)=([],[],[],[])    #4位牌手各自牌的编号列表
root=Tk()
cv=Canvas(root,bg='white',width=700,height=600)
imgs=[]
for i in range(1,5):
    for j in range(1,14):
        imgs.insert((i-1)*13+(j-1),PhotoImage(file='D:\\python\\images
                                              \\'+str(i)+'-'+str(j)+'.gif'))
for x in range(13):
        m=x*4
        p1.append(pocker[m])
        p2.append(pocker[m+1])
        p3.append(pocker[m+2])
        p4.append(pocker[m+3])
p1.sort()
p2.sort()
p3.sort()
p4.sort()
for x in range(0,13):
        img=imgs[p1[x]]
        player1.append(cv.create_image((200+20*x,80),image=img))
        img=imgs[p2[x]]
        player2.append(cv.create_image((100,150+20*x),image=img))
        img=imgs[p3[x]]
        player3.append(cv.create_image((200+20*x,500),image=img))
        img=imgs[p4[x]]
        player4.append(cv.create_image((560,150+20*x),image=img))
print("player1:",player1)
print("player2:",player2)
print("player3:",player3)
print("player4:",player4)
cv.pack()
root.mainloop()

 

你可能感兴趣的:(Python程序设计应用教程 第7章 Tkinter图形界面设计)