图形用户界面(GUI、Graphical User Interface)是基于图形的界面,windows就是一个图形用户界面的操作系统,而DOS是基于字符命令交互的操作系统。图形用户界面由窗口构成,每个窗口都由标题、菜单、控制按钮、滚动条等元素组成。
图形用户界面(GUI)程序也成为桌面(Desktop)程序,是人机交互的图形化的程序。
用Python也可以写出漂亮的桌面程序, Python支持多种图形界面的包(packages)较多,常见的有:
☆ tkinter: tkinter 可以在大多数的 Unix 平台下使用,同样可以应用在 Windows 和 Macintosh 系统里。它是 Python 自带的 GUI 库(libraries),不需要安装,直接导入 tkinter包(packages)即可使用。在此主要介绍tkinter包(packages)。参见Tk图形用户界面(GUI)在线帮助:https://docs.python.org/3.9/library/tk.html
☆ wxPython:wxPython 是一款开源软件,是 Python 语言的一套优秀的 GUI 图形库,允许 Python 程序员很方便的创建完整的、功能键全的 GUI 用户界面。
☆ PyQt:优点界面美观,多个平台,文档和教程丰富。PyQt实现了一个Python模块集。它有超过300类,将近6000个函数和方法。它是一个多平台的工具包,可以运行在所有主要操作系统上,包括UNIX,Windows和Mac。 PyQt采用双许可证,开发人员可以选择GPL和商业许可。在此之前,GPL的版本只能用在Unix上,从PyQt的版本4开始,GPL许可证可用于所有支持的平台。
可将一个窗口看成可被分解的一个空的容器,容器里装了大量的基本组件,通过设置这些基本组件的大小、位置等属性,将空的容器和基本组件组成一个整体的窗口。所以,可将图形界面编程看作是拼图游戏,创建图形用户界面的过程就是完成拼图的过程。
学习 GUI 编程的总体步骤可分为下面三步:
(1)、了解 GUI 包大致包含哪些组件,就相当于熟悉每个积木块到底是些什么东西。
(2)、掌握容器及容器对组件进行布局的方法。
(3)、逐个掌握各组件的用法,则相当于深入掌握每个积木块的功能和用法。
【附注:包(package)、模块(Module)和库(library)
包(package)由分层模块(Module)构成的包。库(library)这个词,一般是针对其他的编译型语言,如C,C#等。
在Python中,module:单个的模块,一般是单个(偶尔为多个)python文件;
package:多个相关的module的组合。肯定是多个,相关的,Python文件的组合;package是用来把相关的模块组织在一起,成为一个整体的。
参见Python中的module,library,package之间的区别:https://blog.51cto.com/5148737/1637888 】
下面介绍使用tkinter来开发GUI编程。
tkinter不需要安装,直接导入 tkinter 即可使用。
tkinter 的 GUI 组件(控件)之间的继承关系参见下图:
Python 的标准编译包含了 tkinter包,这是一个面向对象的接口,指向 Tcl/Tk 组件集(widget set)。
tkinter 的 GUI 组件有两个根父类:1)、Misc:它是所有组件的根父类;2)、Wm:它主要提供了一些与窗口管理器通信的功能函数。
GUI 编程并不需要直接使用它们,但由于它们是所有 GUI 组件的父类,因此 GUI 组件都可以直接使用它们的方法。
Misc 和 Wm 派生了一个子类:Tk,它代表应用程序的主窗口。因此,所有 Tkinter GUI 编程通常都需要直接或间接使用该窗口类。
BaseWidget 是所有组件的基类,它还派生了一个子类:Widget。Widget 代表一个通用的 GUI 组件。Tkinter 所有的 GUI 组件都是Widget 的子类。
Widget 的父类有四个,除 BaseWidget 之外,还有 Pack、Place 和 Grid,这三个父类都是布局管理器,它们负责管理所包含的组件的大小和位置。
图中右边的 Widget 的子类,这些都是 Tkinter GUI 编程的各种 UI 组件。
【附注:函数(function)与方法(method)
本质都是对一段功能代码。
与类和实例无绑定关系的function属于函数(function);
与类和实例有绑定关系的function属于方法(method)。
从它们本质都是对一段功能的抽象来看没啥区别,只不过在类里函数就叫方法,即方法是属于对象的函数,是函数的一种类型。许多资料有时将方法也称为函数,本文亦如此。】
tkinter的组件(小部件、控件、widgets【注】)
【注:tkinte文档中使用的widgets,在许多不同的翻译:组件、小部件、控件,相当于某些开发语言的Components(组件)、controls(控件)】
可以使用tkinter.Tk() 方法生成窗口(窗体),例如(提示:要特别注意其中的大小写,否则出错):
import tkinter
w=tkinter.Tk()
或
import tkinter as tk
w=tk.Tk()
或
from tkinter import *
w= Tk()
窗口(窗体)组件的属性
作用 |
实例 |
|
title |
设置窗口标题 |
window.title(‘xxxxx’) |
geometry |
设置窗口大小,中间不能是*,而是x,加数调整窗口在屏幕上的位置,第1个加数是距离屏幕左边的宽,第2个加数是距离屏幕顶部的高。且有引号 |
window.geometry('600x400+300+200') |
resizable |
设置窗口是否可以变化高(height)、 宽(width),True为可以变化,False为不可变化 |
window.resizable(width=False, height=True) 或 window.resizable(0,1) |
mainloop |
进入消息循环 |
window.mainloop() |
quit |
退出; |
window.quit() |
一个简单的例子、
import tkinter as tk
root = tk.Tk()
root.resizable(0,0)
root.geometry('600x400')
root.geometry('+300+200')
#可以将上两句何为root.geometry('600x400+300+200')
运行之,参见下图:
使用tkinter.Tk生成一个主窗口对象,之后才可以向里面添加组件(文本框、按钮、标签)对象实现GUI开发。
几何管理对象
tkinter 提供三种几何(geometry)管理对象[也叫布局(layout),它提供3种方法:pack、grid 和 place管理同在一个父组件下的所有组件的布局(摆放)。
☆ pack 是按添加顺序排列组件,适用于少量组件的排列,使用较为简单。
☆ grid 是按行/列形式排列组件,grid 把组件(控件)位置作为一个二维表结构来维护, 即按照行列的方式排列组件,组件位置由其所在的行号和列号决定。 行号相同而列号不同的几个组件会被彼此上下排列; 列号相同而行号不同的几个组件会被彼此左右排列。使用 Grid 布局的过程就是为各个组件指定行号和列号的过程. 不需要为每个格子指定大小, Grid 布局会自动设置一个合适的大小。
☆ place 可以指定组件的绝对位置或相对于其他组件的位置,可以指定组件的大小,可以直接根据与父窗口的关系(位置)直接放到想要的位置,可以让组件覆盖到另一个组件上。
pack方法使用语法
WidgetObject.pack(option, …)
其中,WidgetObject代表组件对象,option代表属性
属性参数:
after: |
将组件置于其他组件之后; |
before: |
将组件置于其他组件之前; |
anchor: |
组件的对齐方式,顶对齐'n',底对齐's',左'w',右'e' |
side: |
组件在主窗口的位置,可以为'top','bottom','left','right'(使用时tkinter.TOP,tkinter.LEFT); |
fill: |
填充方式 (Y,垂直,X,水平,BOTH,水平+垂直),是否在某个方向充满窗口 |
expand |
1可扩展,0不可扩展,代表控件是否会随窗口缩放 |
pack布局例子1
简单的将三个 Label 控件 pack 到其父窗口上, 可以使用 fill=X 属性让它们和其父窗口一样宽
from Tkinter import *
root = tk()
root.geometry("350x150") #设置窗体的大小
w = Label(root, text="Red Sun", bg="red", fg="white")
w.pack(fill=X)
w = Label(root, text="Green Grass", bg="green", fg="black")
w.pack(fill=X)
w = Label(root, text="Blue Sky", bg="blue", fg="white")
w.pack(fill=X)
运行之,参见下图:
pack布局例子2
上面那几个 Label 从左到右放在一排,可以使用side :
from tkinter import *
root = Tk()
root.geometry("350x150") #设置窗体的大小
w = Label(root, text="red", bg="red", fg="white")
w.pack(padx=5, pady=10, side=LEFT)
w = Label(root, text="green", bg="green", fg="black")
w.pack(padx=5, pady=20, side=LEFT)
w = Label(root, text="blue", bg="blue", fg="white")
w.pack(padx=5, pady=20, side=LEFT)
运行之,参见下图:
grid方法使用语法
WidgetObject.grid(option, …)
其中,WidgetObject代表组件对象,option代表属性
属性参数:
column: |
组件所在的列起始位置; |
columnspan: |
组件的列宽;跨列数 |
row: |
组件所在的行起始位置; |
rowspan: |
组件的行宽;rowspam=3 跨3行 |
sticky |
对齐方式:NSEW(北南东西)上下左右 |
padx、pady |
x方向间距、y方向间距(padx=5) |
例、
from tkinter import *
root = Tk()
root.geometry("350x150") #设置窗体的大小
colours = ['red','green','orange','white','yellow','blue']
r = 0
for c in colours:
Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0)
Entry(bg=c, relief=SUNKEN,width=10).grid(row=r,column=1)
r = r + 1
运行之,参见下图:
place方法
使用语法
WidgetObject.place(option, …)
其中,WidgetObject代表组件对象,option代表属性
属性参数:
anchor: |
组件对齐方式;n, ne, e, se, s, sw, w, nw, or center ; ('n'==N) |
x: |
组件左上角的x坐标; |
y: |
组件左上角的y坐标; |
relx: |
组件左上角相对于窗口的x坐标,应为0-1之间的小数;图形位置相对窗口变化 |
rely: |
组件左上角相对于窗口的y坐标,应为0-1之间的小数; |
width: |
组件的宽度; |
heitht: |
组件的高度; |
relwidth: |
组件相对于窗口的宽度,0-1之间的小数,图形宽度相对窗口变化; |
relheight: |
组件相对于窗口的高度,0-1之间的小数; |
例、
from tkinter import *
root = Tk()
root.geometry("350x150") #设置窗体的大小
lb = Label(root, text='hello Place')
# 使用绝对坐标将Label放置到(0,0)位置上
lb.place(x=0, y=0, anchor=NW)
lb2 = Label(root, text='hello Place')
# 使用相对坐标(0.5,0.5)将Label放置到(0.5*sx,0.5.sy)位置上
lb2.place(relx=0.5, rely=0.5, anchor=CENTER)
运行之,参见下图:
常规组件介绍:
★ Label:标签组件,使用语法:
w = tkinter.Label(parent, option, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
属性简析 |
实例 |
text |
需要在界面显示的Label标签内容 |
Label(root,text=‘xxxxx’) |
height |
组件的高度(所占行数) |
Label(root,text=‘xxxxx’,height=2) |
width |
组件的宽度(所占字符个数) |
Label(root,text=‘xxxxx’,height=2,width=20) |
fg |
前景字体颜色 |
Label(root,text=‘xxxxx’,fg='blue')---显示字体为蓝色 |
bg |
背景颜色 |
Label(root,text=‘xxxxx’,bg=‘red’)---显示背景为红色 |
justify |
多行文本的对齐方式,可选参数为: LEFT、 CENTER、RIGHT,分别是向左、居中、向右对齐 |
Label(root,text=‘xxxxx’,justify=tk.LEFT) |
padx |
文本左右两侧的空格数(默认为1) |
Label(root,text=‘xxxxx’,padx=5) |
pady |
文本上下两侧的空格数(默认为1) |
Label(root,text=‘xxxxx’,pady=5) |
font |
设置字体格式和大小 |
Label(root,text=‘xxxxx’,font=("微软雅黑", 12)) |
photo |
设置背景图片,事先需要指定图片路径 |
photo=tk.PhotoImage(file='指定图片路径') Label(root,text=‘xxxxx’,image=photo) |
compound |
图像背景图位置,可选参数为:botton、top、right、left、center(下、上、右、左、文字覆盖图像) |
photo=tk.PhotoImage(file='指定图片路径') Label(root,text=‘xxxxx’,image=photo,compound=center) |
例、
import tkinter
root_window = tkinter.Tk()
root_window.title('Tkinter_Demo')
root_window.geometry('400x300')
hello_label = tkinter.Label(root_window, text='hello world', bg='red', width=10, height=2)
hello_label.pack(side=tkinter.TOP) # 这里的side可以赋值为LEFT RTGHT TOP BOTTOM
root_window.mainloop()
运行之,参见下图:
★ Button:按钮组件,使用语法:
tkinter.Button(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
属性简析 |
实例 |
text |
按钮图标显示内容 |
Button(root,text='xxxx') |
height |
组件的高度(所占行数) |
Button(root,text='xxxx',height=2) |
width |
组件的宽度(所占字符个数) |
Button(root,text='xxxx',width=20) |
fg |
前景字体颜色 |
Button(text='xxxx',fg='blue')---显示按钮字体颜色为蓝色 |
bg |
背景颜色 |
Button(root,text='xxxx',bg='red')---显示按钮背景为红色 |
activebackground |
按钮按下时的背景颜色 |
Button(root,text='xxxx',activebackground='grey') |
activeforeground |
按钮按下时的前景字体颜色 |
Button(root,text='xxxx',activeforeground='white') |
justify |
多行文本的对齐方式,可选参数为: LEFT、 CENTER、RIGHT,分别是向左、居中、向右对齐 |
Button(root,text=‘xxxxx’,justify=tk.LEFT) |
padx |
文本左右两侧的空格数(默认为1) |
Button(root,text='xxxx',padx=10) |
pady |
文本上下两侧的空格数(默认为1) |
Button(root,text='xxxx',pady=10) |
command |
按钮触发执行的命令(函数) |
Button(root,text='xxxx',command=函数) |
例、
import tkinter
def button_clicked():
m_label.config(text='button clicked')
root_window = tkinter.Tk()
root_window.title('tkinter_Demo')
root_window.geometry('400x300')
m_label = tkinter.Label(root_window, text='这里是是标签', bg='red', width=20, height=2)
m_label.pack(side=tkinter.TOP)
m_button = tkinter.Button(root_window, text='button', command=button_clicked)
m_button.pack()
★ Entry:输入文本框组件,使用语法:
tkinter.Entry(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
属性简析 |
实例 |
width |
组件的宽度(所占字符个数) |
Entry(root,width=20) |
fg |
前景字体颜色 |
Entry(root,fg='blue') |
bg |
背景颜色 |
Entry(root,bg='blue') |
show |
将Entry框中的文本替换为指定字符,用于输入密码等,如设置 show="*" |
Entry(root,show="*") |
state |
设置组件状态,默认为normal,可设置为:disabled—禁用组件,readonly—只读 |
Entry(root,state=readonly) |
textvariable |
指定变量,需要事先定义一个变量,在Entry进行绑定获取变量的值 |
text=tk.StringVar() |
例、
import tkinter
root_window = tkinter.Tk()
root_window.title('tkinter_Demo')
root_window.geometry('400x300')
m_str_var = tkinter.StringVar()
m_entry = tkinter.Entry(root_window, textvariable=m_str_var)
m_str_var.set('hello world')
m_entry.pack()
运行之,参见下图:
再给出一个复杂点的例
import tkinter as tk #导入tkinter库,并重命名为tk
mywindow = tk.Tk() #创建一个窗体
mywindow.title("输入文本框控件的应用") #设置窗体的标题
mywindow.geometry("350x150") #设置窗体的大小
#自定义mychick()函数,当单击按钮时调用
def mychick() :
mynum = float(mytext.get())
mylab.config(text="%f摄氏度=%f华氏度" %(mynum,mynum*1.8+32))
#标签控件
mylab = tk.Label(mywindow,
text="摄氏度和华氏度的转换,在文本框中输入摄氏度",
fg = "yellow",
bg= "red",
font=("Arial",12),
width = 100,
height = 5
)
mylab.pack() #布局标签的位置
#输入文本框控件
mytext = tk.Entry(mywindow,text="",width = 80 )
mytext.pack()
#按钮控件
mybut = tk.Button(mywindow,text="摄氏度转换为华氏度",command= mychick )
mybut.pack()
运行之,参见下图:
★ Radiobutton:单选按钮组件,使用语法:
tkinter.Radiobutton(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
属性简析 |
实例 |
text |
单选框文本显示内容 |
Radiobutton(root,text='xxxx') |
variable |
单选框索引变量,通过变量的值确定哪个单选框被选中。一组单选框使用同一个索引变量,需要事先设定一个变量 |
color=tk.StringVar() |
value |
单选框选中时设定变量的值 |
color=tk.StringVar() |
command |
单选框选中时执行的命令(函数) |
color=tk.StringVar() |
例、
import tkinter as tk
root = tk.Tk()
root.geometry("350x150") #设置窗体的大小
LANGS = [("python",1),("C",2),("Java",3),("Scratch",4)]
v = tk.IntVar()
v.set(1)#把v的值设置为1
for lang,num in LANGS:
#选中后 把num的值赋给 variable
b = tk.Radiobutton(root,text=lang,variable = v ,value =num)
b.pack(anchor = tk.W)
l = tk.Label(root,textvariable=v)#显示标签
l.pack(side=tk.LEFT)
运行之,参见下图:
★ Checkbutton:复选按钮组件,使用语法:
tkinter.Checkbutton(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
属性简析 |
实例 |
text |
复选框显示的文本 |
Checkbutton(root,text='xxxx') |
variable |
复选框索引变量,通过变量的值确定哪些复选框被选中。每个复选框使用不同的变量,使复选框之间相互独立,事先需要定义不同的变量 |
typeBlod=tk.IntVar() |
onvalue |
复选框选中(有效)时变量的值,可以通过计算值来判断分支不同的效果,计算值由自己设定 |
typeBlod=tk.IntVar() |
offvalue |
复选框未选中(无效)时变量的值,可以通过计算值来判断分支不同的效果,一般设置为0 |
typeBlod=tk.IntVar() |
command |
复选框选中时执行的命令(函数) |
typeBlod=tk.IntVar() |
例、
import tkinter as tk
root = tk.Tk()
root.geometry("350x150") #设置窗体的大小
GIRLS =['西施','貂蝉','王昭君','杨玉环']
v = []
for girl in GIRLS:#显示四大美女的显示框
v.append(tk.IntVar())
#variable:把变量放到最后一个 ,
b = tk.Checkbutton(root,text=girl,variable = v[-1])
b.pack(side = tk.LEFT)
for each in v:#显示状态的框
l = tk.Label(root,textvariable=each)
l.pack(side = tk.LEFT)
运行之,参见下图:
★ Text:多行文本框组件,Text 组件(控件)可以显示网页链接, 图片, HTML页面, 甚至 CSS 样式表,使用语法:
tkinter.text(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
解释 |
undo |
是否使能撤销功能,使用False和True设置 |
maxundo |
撤销的最大次数 |
… |
… |
Text 组件十分的强大和灵活,适用于多种任务。
插入操作方法:t.insert(Indexs, 内容)
其中,Indexs(索引号)指向Text组件中文本的位置,有不同的索引类型,如:
x.y:其中x行号以1开始, y列号以0开始
"insert"
"end"
tkinter.INSERT,tkinter.CURRENT:鼠标的当前位置所对应的字符位置
tkinter.END:这个Textbuffer的最后一个字符
tkinter.SEL_FIRST:选中文本域的第一个字符,如果没有选中区域则会引发异常
tkinter.SEL_LAST:选中文本域的最后一个字符,如果没有选中区域则会引发 异常
获得 Text 组件的内容,可以使用 get() 方法(仅获取文本内容),如:
contents = text.get(1.0, "end")
使用 search() 方法可以搜索 Text 组件中的内容。
Text 组件还支持“恢复”和“撤销”操作。
例1、
import tkinter as tk
root = tk.Tk()
root.geometry('400x300')
text = tk.Text(root,width=30, height=2) #30的意思是30个平均字符的宽度,height设置为两行
text.pack()
# "insert" 索引表示插入光标当前的位置
text.insert("insert", "I love ")
text.insert("end", "Python.com!")
root.mainloop()
运行之,参见下图:
例2、
import tkinter
root_window = tkinter.Tk()
root_window.title('tkinter_Demo')
root_window.geometry('400x300')
m_text = tkinter.Text(root_window)
m_text.insert(tkinter.CURRENT, 'hello \n')
m_text.insert(tkinter.END, 'world \n')
m_text.insert(tkinter.END, 'nono')
m_text.pack()
运行之,参见下图:
例3、简单的文本读写的例子——简易记事本
import tkinter as tk #导入tkinter库,并重命名为tk
from tkinter import filedialog #从tkinter库中导入filedialog模块
from tkinter import messagebox #从tkinter库中导入messagebox模块
import os #导入os标准库
mywindow = tk.Tk() #创建一个窗体
mywindow.title("多行文本框的应用") #设置窗体的标题
mywindow.geometry("400x300") #设置窗体的大小
filename=""
def myopen():
global filename
filename=filedialog.askopenfilename(defaultextension=".txt")
if filename=="":
filename=None
else:
mywindow.title("记事本"+os.path.basename(filename))
mytext.delete(1.0,tk.END)
f=open(filename,'r')
mytext.insert(tk.INSERT,f.read())
f.close()
def mysave():
global filename
f=filedialog.asksaveasfilename(initialfile="未命名.txt",defaultextension=".txt")
filename=f
fh=open(f,'w')
msg=mytext.get(1.0,tk.END)
fh.write(msg)
fh.close()
mywindow.title("记事本"+os.path.basename(f))
#按钮控件及布局
myb1 = tk.Button(mywindow,text="打开",command = myopen)
myb1.pack(side = tk.LEFT)
myb2 = tk.Button(mywindow,text="保存", command = mysave )
myb2.pack()
#文本框及布局
mytext = tk.Text(mywindow)
mytext.pack()
运行之,参见下图:
★ Frame框架组件,在屏幕上创建一块矩形区域,作为其它组件的容器,使用语法:
tkinter.Frame(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
解释 |
bg or background |
Frame控件的背景颜色 |
cursor |
当鼠标在Frame控件区域时需要显示的样式 |
height |
Frame控件的高度 |
width |
Frame控件的宽度 |
… |
… |
例、
import tkinter as tk
window = tk.Tk()
window.title = ('my window')
window.geometry('300x150')
tk.Label(window, text='on the window').pack()
# 在window上创建一个frame
frm = tk.Frame(window, bg='purple')
frm.pack()
# 把上面的frm分成上下两个frame
frm_top = tk.Frame(frm, bg='red', borderwidth=3)
frm_bottom = tk.Frame(frm, bg='blue', borderwidth=3)
# 放置两个frame并指定在外城frame中的相对位置
frm_top.pack(side='top')
frm_bottom.pack(side='bottom')
# 把frm_bottom分成左右两个frame
frm_b_l = tk.Frame(frm_bottom, bg='orange', borderwidth=3)
frm_b_r = tk.Frame(frm_bottom, bg='yellow', borderwidth=3)
# 放置两个frame
frm_b_l.pack(side='left')
frm_b_r.pack(side='right')
# 分别在top,b_l,b_r三个frame中添加内容
tk.Label(frm_top, text='on the frm_top').pack()
tk.Label(frm_b_l, text='on the frm_l').pack()
tk.Label(frm_b_r, text='on the frm_r1').pack()
tk.Label(frm_b_r, text='on the frm_r2').pack()
运行之,参见下图:
★ Listbox列表框组件,使用语法:
tkinter.Listbox(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
解释 |
listvariable |
用于设置列表框中的值,或是获取列表框的值,通过set()与get()方法实现 |
selectbackground |
选中选项的背景色 |
selectmode |
• tk.BROWSE: 缺省的;• tk.SINGLE:只能选中一项,不能拖动鼠标;• tk.MULTIPLE:选中多行;• tk.EXTENDED:选中当前位置到最后 |
… |
… |
例
import tkinter as tk #导入tkinter库,并重命名为tk
from tkinter import messagebox #从tkinter库中导入messagebox模块
mywindow = tk.Tk() #创建一个窗体
mywindow.title("单选列表框的应用") #设置窗体的标题
mywindow.geometry("200x250") #设置窗体的大小
#添加按钮的单击事件代码
def mybutton1click() :
s =mytext.get()
if s != "" :
mylistbox.insert("end",s)
else :
messagebox.showinfo("提示对话框","请输入要添加的内容,不能为空!")
#删除按钮的单击事件代码
def mybutton2click() :
mylistbox.delete("active")
#定义列表变量
mylist = ["C","C++","Python","Java","C#","R","PHP"]
#列表框控件及布局
mylistbox = tk.Listbox(mywindow )
mylistbox.pack()
for i in mylist :
mylistbox.insert("end",i)
#输入文本框及布局
mytext = tk.Entry(mywindow,text="")
mytext.pack()
#两个按钮及布局
mybutton1 =tk.Button(mywindow,text="添加" ,command = mybutton1click )
mybutton1.pack(side=tk.LEFT)
mybutton2 = tk.Button(mywindow,text="删除", command = mybutton2click )
mybutton2.pack(side=tk.LEFT)
运行之,参见下图:
★ Combobox 下拉列表框(组合框)组件,使用语法:
tkinter.Combobox(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
参数 |
描述 |
master |
代表了父窗口 |
height |
设置显示高度、如果未设置此项,其大小以适应内容标签 |
width |
设置显示宽度,如果未设置此项,其大小以适应内容标签 |
state |
可读状态,如state= “readonly” |
textvariable |
设置textvariable属性 |
常用的方法:
方法 | 描述 |
get |
返回制定索引的项值,如listbox.get(1);返回多个项值,返回元组,如listbox.get(0,2);返回当前选中项的索引listbox.curselection() |
values |
设定下拉列表的内容。如 data = ["a","b","c"], cbx["values"] = data |
current(i) |
指定下拉列表生成时显示在列表值,i = index。如current(2),显示列表中的第三个值 |
事件:
下拉列表的虚拟事件是 "<
例、
import tkinter as tk
# 创建窗体
from tkinter import ttk
window = tk.Tk()
window.title('Tk Demo')
window.geometry('350x400')
# 用来显示下拉框值的Label
var = tk.StringVar()
la = tk.Label(window, text="")
la.grid(column=1, row=1)
def click():
la.config(text=number.get())
number = tk.StringVar()
numberChosen = ttk.Combobox(window, width=12, textvariable=number)
numberChosen['values'] = (1, 2, 4, 42, 100) # 设置下拉列表的值
numberChosen.grid(column=1, row=1) # 设置其在界面中出现的位置 column代表列 row 代表行
numberChosen.current(0) # 设置下拉列表默认显示的值,0为 numberChosen['values'] 的下标值
运行之,参见下图:
★ Scrollbar 滚动条组件,使用语法:
tkinter.Scrollbar (parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 |
解释 |
command |
Scrollbar移动的响应方法 |
orient |
控制Scrollbar的位置,可以为Tkinter.HORIZONTAL水平的scrollbar,Tkinter.VERTICAL垂直的 |
… |
… |
例、
import tkinter as tk
root = tk.Tk()
root.geometry('350x400') #设置窗体的大小
sc = tk.Scrollbar(root)
sc.pack(side="right", fill="y")
lb = tk.Listbox(root, yscrollcommand=sc.set)
for i in range(50):
lb.insert("end", str(i))
lb.pack(side="left", fill="both")
sc.config(command=lb.yview)
运行之,参见下图:
★ menu 窗体菜单组件
使用语法:
tkinter.menu (parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性选项 |
含义 |
activebackground |
设置当 Menu 处于 "active" 状态(通过 state 选项设置状态)的背景色 |
activeborderwidth |
设置当 Menu 处于 "active" 状态(通过 state 选项设置状态)的边框宽度 |
activeforeground |
设置当 Menu 处于 "active" 状态(通过 state 选项设置状态)的前景色 |
background |
设置背景颜色 |
bg |
跟 background 一样 |
borderwidth |
指定边框宽度 |
bd |
跟 borderwidth 一样 |
cursor |
指定当鼠标在 Menu 上飘过的时候的鼠标样式 |
disabledforeground |
指定当 Menu 处于 "disabled" 状态的时候的前景色 |
font |
指定 Menu 中文本的字体 |
foreground |
设置 Menu 的前景色 |
fg |
跟 foreground 一样 |
postcommand |
将此选项与一个方法相关联,当菜单被打开的时候该方法将自动被调用 |
relief |
1. 指定边框样式 |
selectcolor |
指定当菜单项显示为单选按钮或多选按钮时选择中标志的颜色 |
tearoff |
1. 默认情况下菜单可以被“撕下”(点击 IDLE 菜单上边的 --------- 试试) |
tearoffcommand |
如果你希望当用户“撕下”你的菜单时通知你的程序,那么你可以将该选项与一个方法相关联,那么当用户“撕下”你的菜单时,Tkinter 会带着两个参数去调用你的方法(一个参数是当前窗口的 ID,另一个参数是承载被“撕下”的菜单的窗口 ID) |
title |
默认情况下,被“撕下”的菜单标题是其主菜单的名字,不过你也可以通过修改此项的值来修改标题 |
菜单组件的方法
add(type, options) 方法
参数
type 参数指定添加的菜单类型,可以是:"command","cascade","checkbutton","radiobutton" 或 "separator"还可以通过 options 选项设置菜单的属性,下表列举了 options 可以使用的选项和具体含义:
选项 |
含义 |
accelerator |
1. 显示该菜单项的加速键(快捷键) |
activebackground |
设置当该菜单项处于 "active" 状态(通过 state 选项设置状态)的背景色 |
activeforeground |
设置当该菜单项处于 "active" 状态(通过 state 选项设置状态)的前景色 |
background |
设置该菜单项的背景颜色 |
bitmap |
指定显示到该菜单项上的位图 |
columnbreak |
从该菜单项开始另起一列显示 |
command |
将该选项与一个方法相关联,当用户点击该菜单项时将自动调用此方法 |
compound |
1. 控制菜单项中文本和图像的混合模式 |
font |
指定文本的字体 |
foreground |
设置前景色 |
hidemargin |
是否显示菜单项旁边的空白 |
image |
1. 指定菜单项显示的图片 |
label |
指定菜单项显示的文本 |
menu |
1. 该选项仅在 cascade 类型的菜单中使用 |
offvalue |
1. 默认情况下,variable 选项设置为 1 表示选中状态,反之设置为 0 |
onvalue |
1. 默认情况下,variable 选项设置为 1 表示选中状态,反之设置为 0 |
selectcolor |
指定当菜单项显示为单选按钮或多选按钮时选择中标志的颜色 |
selectimage |
如果你在单选按钮或多选按钮菜单中使用图片代替文本,那么设置该选项指定被菜单项被选中时显示的图片 |
state |
1. 跟 text 选项一起使用,用于指定哪一个字符画下划线(例如用于表示键盘快捷键) |
underline |
1. 用于指定在该菜单项的某一个字符处画下划线 |
value |
1. 当菜单项为单选按钮时,用于标志该按钮的值 |
variable |
1. 当菜单项是单选按钮或多选按钮时,与之关联的变量 |
add_cascade(options) 方法
添加一个父菜单
相当于 add("cascade", options)
add_checkbutton(options) 方法
添加一个多选按钮的菜单项
相当于 add("checkbutton", options)
add_command(options) 方法
添加一个普通的命令菜单项
相当于 add("command", options)
add_radiobutton(options) 方法
添加一个单选按钮的菜单项
相当于 add("radiobutton", options)
add_separator(options) 方法
添加一条分割线
相当于 add("separator", options)
add_separator(options) 方法
添加一条分割线
相当于 add("separator",*options)
unpost()方法
移除弹出菜单
例、
import tkinter as tk
root = tk.Tk()
root.geometry('550x400') #设置窗体的大小
def callback():
print("~被调用了~")
# 创建一个顶级菜单
menubar = tk.Menu(root)
# 创建一个下拉菜单“文件”,然后将它添加到顶级菜单中
filemenu = tk.Menu(menubar, tearoff=False)
filemenu.add_command(label="打开", command=callback)
filemenu.add_command(label="保存", command=callback)
filemenu.add_separator()
filemenu.add_command(label="退出", command=root.quit)
menubar.add_cascade(label="文件", menu=filemenu)
# 创建另一个下拉菜单“编辑”,然后将它添加到顶级菜单中
editmenu = tk.Menu(menubar, tearoff=False)
editmenu.add_command(label="剪切", command=callback)
editmenu.add_command(label="拷贝", command=callback)
editmenu.add_command(label="粘贴", command=callback)
menubar.add_cascade(label="编辑", menu=editmenu)
# 显示菜单
root.config(menu=menubar)
运行之,参见下图:
右键菜单例子、
import tkinter
win = tkinter.Tk()
win.title("Software v1") #窗口标题
win.geometry("500x300+200+20") #窗口位置500后面是字母x
# 鼠标右键菜单
menubar = tkinter.Menu(win) #创建菜单条
xMenu = tkinter.Menu(menubar, tearoff=False) #创建子菜单
for item in ["子菜单1", "子菜单2", "子菜单3", "子菜单4", "子菜单5"]:
xMenu.add_command(label=item)
menubar.add_cascade(label="右键总菜单1", menu=xMenu) #创建总菜单,将子菜单绑定进来
def xShowMenu(event):
menubar.post(event.x_root, event.y_root) #将菜单条绑定上事件,坐标为x和y的root位置
win.bind("
win.mainloop() #窗口持久化
运行之,参见下图:
★ Canvas 画布组件
Canvas 是一个灵活通用的组件,通常用于显示和编辑图形。你可以用它来绘制线段、圆形、多边形,甚至是绘制其它组件。
使用语法:
tkinter.Entry(parent, option=value, ...)
其中,parent可以理解成父窗口,option代表属性。
属性 说明
bd 指定画布的边框宽度,单位是像素
bg 指定画布的背景颜色
confine 指定画布在翻滚区域外是否可以滚动,默认值为True,表示不能翻滚
cursor 指定画布中的鼠标指针
heihgt 指定画布高度
highlightcolor 选中画布时的背景颜色
relief 指定画布的边框样式,
scrollregion 指定画布的翻滚区域的元组(w,n,e,s)
Canvas 提供了如下方法来绘制各种图形:
reate_arc:绘制弧,格式:create_acr( (x1, y1, x2, y2),选项.....)
其中
x1, y1 代表弧外框矩形左上角的坐标
x2, y2 代表弧外框矩形右下角的坐标
选项:
outline: 图形轮廓颜色
fill: 图像的填充颜色
width: 圆弧边框的宽度
start: 圆弧的起始角度
extent: 圆弧的偏移角度
例、
#画弧线
import tkinter as tk
window=tk.Tk()
window.title("Canvas组件!")
window.geometry("300x200")
w = tk.Canvas(window, width=200, height=400)
w.pack()
arc1 = w.create_arc((50,10,110,110),
fill='darkblue',
extent=30,
start=90,
outline='red')
运行之,参见下图:
create_rectangle() 绘制矩形。需要指定两个点的坐标,分别作为矩形左上角点和右下角点的坐标。
create_oval() 方法绘制椭圆(包括圆,圆是椭圆的特例)。要指定两个点的坐标,分别作为左上角点和右下角点的坐标来确定一个矩形,而该方法则负责绘制该矩形的内切椭圆。
create_bitmap:绘制位图。【注】、
create_image:绘制图片。【注】、
create_line():绘制直线。需要指定两个点的坐标,分别作为直线的起点和终点。
create_polygon:绘制多边形。指定多个点的坐标来作为多边形的多个顶点。
create_text:绘制文字。【注】、
create_window:绘制组件。【注】、
【注】、 create_bitmap、create_image、create_text、create_window 等方法时,只要指定一个坐标点,用于指定目标元素的绘制位置即可。
在此,除reate_arc外,未提及具体选项,但绘制这些图形时都可指定选项。
Canvas 的坐标系统是绘图的基础,其坐标原点在左上角,横坐标向右,纵坐标向下,参见下图:
例1、
from tkinter import *
master = Tk()
cv = Canvas(master, width=640, height=480, bd=0)
cv.pack()
line_coords = (300, 50, 300, 400)
cv.create_line(*line_coords, fill='red')
line_coords = (50, 200, 600, 200)
cv.create_line(*line_coords, fill='blue')
运行之,参见下图:
例2、实现点击按钮,红色圆会移动,代码如下
import tkinter as tk
window=tk.Tk()
window.title("Canvas组件!")
window.geometry("300x200")
canvas=tk.Canvas(window,bg="blue",height=100,width=100)
circle=canvas.create_oval(25,25,75,75,fill='red') #创建圆形,填充颜色为红色
#四个参数为圆外接正方形的左上角和右下角的顶点坐标
canvas.pack()
def move():
canvas.move(circle,2,2) #每次下移2个单位,右移2个单位
bn=tk.Button(window,text="移动圆",command=move)
bn.pack()
window.mainloop()
运行之,参见下图:
tkinter对话框子模块
包括:消息框messagebox、简单对话框simpledialog、文件对话框filedialog、颜色选择对话框colorchooser子模块。
★ 消息框messagebox
messagebox包括两个系列的函数,ask和show系列的函数,从字面上理解,ask是问,故名意思是一种典型的对话框,这种对话框的特性是拥有多个按钮,而show系列的函数的功能往往是用于显示一些信息。
不管是ask还是show系列的函数,参数都是一样的:
1)title:设置标题栏的文本
2)message:设置对话框的主要文本内容,可以用’\n’来实现换行
3)options:选项,这是可选的。可以使用两项:
default:此选项用于指定消息框中的默认按钮,如ABORT、RETRY或IGNORE。
parent:此选项用于指定要在其上显示消息框的窗口。
先看5个ask系列函数
☆askyesno函数
import tkinter
tkinter.messagebox.askyesno("askyesno","显示yes和no按钮 问号图标")
返回一个bool类型,如果yes被点击,返回True,no被点击,返回False
☆askquetion函数
tkinter.messagebox.askquestion("askquestion","显示yes和no按钮 问号图标 和askyesno大致相同,不同的是返回值")
与askyesno函数不同的只有返回值,askquetion返回一个字符串,如果yes被点击则返回yes,no被点击则返回no
☆askokcancel函数则是显示ok按钮和cancel(取消)按钮,我们在这种情况下会用到——例如询问用户是否安装。
tkinter.messagebox.askokcancel("askokcancel函数应用","您要继续安装吗?")
askokcancel函数的返回值为一个bool类型,如果ok被点击返回True,cancel被点击则返回False
☆askyesnocancel函数显示3个按钮,分别是yes、no、cancel。我们在这种情况下会用上,例如询问用户是否继续。
tkinter.messagebox.askyesnocancel("askyesnocancel函数应用","程序出现了某种错误,是否继续运行?点击取消撤销当前更改")
askyesnocancel函数也是一个bool类型,当yes按钮被点击,返回True,no按钮被点击返回False,如果cancel被点击返回一个None
☆askretrycancel函数显示一个retry按钮(重试)和cancel按钮(取消)。
例如询问用户程序读取文件失败,是否重试。
tkinter.messagebox.askretrycancel("askretrycancel函数应用","很不幸,读取***文件失败,是否重试?")
askretrycancel函数的返回值同为bool类型,如果retry按钮被点击,返回True,cancel按钮被点击返回False
show系列的3个函数:
☆showinfo函数
show系列最常用的一个函数就是showinfo,该方法用于显示一个ok按钮(当然showinfo函数可以点击右上角的x号关闭),所以其实返回值我们没有多大必要去了解,showinfo的返回值是返回一个字符串,当点击ok按钮时,返回ok字符串,点击右上角的x关闭对话框,同样是返回一个ok字符串。
tkinter.messagebox.showinfo("showinfo函数应用","sucess!")
☆showinfo函数则是用于显示警告信息:
tkinter.messagebox.showwarning("showwarning函数应用","检测到您当前的系统版本不是正版,珍爱生命,远离盗版")
返回值和showinfo函数相同,同是返回一个ok字符串。
☆showerror函数则是用于显示错误信息:
tkinter.messagebox.showerror("showerror","程序错误")
返回值一样是一个ok字符串。
例、修改tk窗口的默认图标,可以使用iconbitmap函数进行修改(本例需要D:\\testA下有一个C1.ico的图标文件),并用messagebo消息框给予提示。
import tkinter
import tkinter.messagebox #这个是消息框,对话框的关键
win = tkinter.Tk()
win.title("Software v1") #窗口标题
win.geometry("500x300+200+20") #窗口位置500后面是字母x
win.iconbitmap("D:\\testA\\C1.ICO")
tkinter.messagebox.showinfo("看图标哦","哈哈,我修改了")
win.mainloop() #窗口持久化
运行之,参见下图:
★ 简单对话框simpledialog
提供了3个函数用来提示用户输入所需类型的值
浮点数:askfloat(title, prompt, initialvalue)
整数:askinteger(title, prompt, initialvalue)
字符串:askstring(title, prompt, initialvalue)
它们通过GUI窗口的方式,让用户输入一个整数,浮点数,或者字符串,并且自带输入合法性检测! 返回你输入的值,点击Cancel,返回None,直接关闭此对话框,返回None。
例、
# 简单对话框,包括字符、整数和浮点数
import tkinter as tk
from tkinter import simpledialog
def input_str():
r = simpledialog.askstring('字符录入', '请输入字符', initialvalue='hello world!')
if r:
print(r)
label['text'] = '输入的是:' + r
def input_int():
r = simpledialog.askinteger('整数录入', '请输入整数', initialvalue=100)
if r:
print(r)
label['text'] = '输入的是:' + str(r)
def input_float():
r = simpledialog.askfloat('浮点数录入', '请输入浮点数', initialvalue=1.01)
if r:
print(r)
label['text'] = '输入的是:' + str(r)
root = tk.Tk()
root.title('对话框')
root.geometry('300x100+300+300')
label = tk.Label(root, text='输入对话框,包括字符、整数和浮点数', font='宋体 -14', pady=8)
label.pack()
frm = tk.Frame(root)
btn_str = tk.Button(frm, text='字符', width=6, command=input_str)
btn_str.pack(side=tk.LEFT)
btn_int = tk.Button(frm, text='整数', width=6, command=input_int)
btn_int.pack(side=tk.LEFT)
btn_int = tk.Button(frm, text='浮点数', width=6, command=input_float)
btn_int.pack(side=tk.LEFT)
frm.pack()
root.mainloop()
运行之,参见下图:
★ 文件对话框filedialog
☆filedialog.askopenfilename(options)
自动打开选取窗口,手动选择一个文件,返回文件路径,类型为字符串。
可选参数:title、filetypes、initialdir、multiple
☆filedialog.askopenfilenames(options)
同时选择多个文件,返回一个元组,包括所有选择文件的路径。
可选参数:title、filetypes、initialdir
☆filedialog.asksaveasfile(options)
选择文件存储路径并命名,可选参数:title、filetypes、initialdir、efaultextension
如果 filetypes=[(“文本文档”, “.txt”)] ,可以不写文件扩展名,扩展名自动为txt;
如果 *filetypes=[(‘All Files’, ’ ')] ,一定写文件扩展名,否则无扩展名;
如果 filetypes=[(“文本文档”, “.txt”)] ,efaultextension=‘.tif’,可以不写文件扩展名,扩展名自动为tif。
☆filedialog.askdirectory(options)
选择一个文件夹,返回文件夹路径。
可选参数:title、initialdir
参数说明
★title --指定文件对话框的标题栏文本。(对选择文件时进行提示,建议必写该参数)。
★defaultextension --指定文件的后缀,例如:defaultextension=’.jpg’,那么当用户输入一个文件名’Python’的时候,文件名会自动添加后缀为’Python.jpg’ 。–注意:如果用户输入文件名包含后缀,那么该选项不生效。(不必须)
★filetypes --指定筛选文件类型的下拉菜单选项,该选项的值是由二元组构成的列表,每个二元组是由(类型名,后缀)构成,例如:
filetypes=[(‘文本’, ‘.txt’), (‘动图’, ‘.gif’)]
比较复杂的例子:
filetypes= [("PNG图片; GIF图片", "*.png; *.gif"), ("HTML files", "*.html;*.htm"), ("All files", "*.*")] 请注意英语分号、逗号、括号的用法。
★initialdir --指定打开保存文件的默认路径,默认路径是当前文件夹。(不必须)
★multiple --是否确定选择多个文件,if true user may select more than one file。(不必须)
例1、编写一个图形界面,使用filedialog文件对话框选择一个Excel文件
from tkinter import *
from tkinter import filedialog
import tkinter.messagebox
def main():
def selectExcelfile():
sfname = filedialog.askopenfilename(title='选择Excel文件', filetypes=[('Excel', '*.xlsx'), ('All Files', '*')])
print(sfname)
text1.insert(INSERT,sfname)
def closeThisWindow():
root.destroy()
def doProcess():
tkinter.messagebox.showinfo('提示','处理Excel文件的示例程序。')
#初始化
root=Tk()
#设置窗体标题
root.title('Python GUI Learning')
#设置窗口大小和位置
root.geometry('500x300+570+200')
label1=Label(root,text='请选择文件:')
text1=Entry(root,bg='white',width=45)
button1=Button(root,text='浏览',width=8,command=selectExcelfile)
button2=Button(root,text='处理',width=8,command=doProcess)
button3=Button(root,text='退出',width=8,command=closeThisWindow)
label1.pack()
text1.pack()
button1.pack()
button2.pack()
button3.pack()
label1.place(x=30,y=30)
text1.place(x=100,y=30)
button1.place(x=390,y=26)
button2.place(x=160,y=80)
button3.place(x=260,y=80)
root.mainloop()
main()
运行之,参见下图:
例2、一个图片查看器——使用filedialog模块打开文件,显示图片需要配合使用“画布”(Canvas)和“图像”(PhotoImage)组件(tkinter支持的图片格式有PNG和GIF等),代码如下:
"""tkimage.pyw 简单的图片查看器
"""
import tkinter as tk
import tkinter.filedialog as fd
def openimage(canvas):
"""事件处理函数:使用文件对话框打开图片
"""
filename = fd.askopenfilename(filetypes=[("PNG图片; GIF图片", "*.png; *.gif"),
("PNG图片", "*.png"),
("GIF图片", "*.gif")])
global image # 注意这个需要定义为全局变量
image = tk.PhotoImage(file=filename)
canvas.create_image((0, 0), image=image, anchor="nw")
def main():
"""主函数:设置窗口部件,指定按钮点击事件处理函数
"""
window = tk.Tk()
window.geometry("600x480")
window.title("简单的图片查看器")
canvas = tk.Canvas(window, width=600, height=440)
canvas.pack(side="bottom")
button = tk.Button(window, text="打开图片",
command=lambda: openimage(canvas))
button.pack()
tk.mainloop()
main()
运行之,参见下图:
★ 颜色选择对话框colorchooser
颜色对话框提供了一个界面让用户选择需要的颜色。
colorchooser 模块提供了一个函数 askcolor(color, option=value, ...)
函数参数
参数 |
含义 |
color |
--要显示的初始的颜色(下图四个红箭头指的地方) --默认颜色是浅灰色(light gray) |
parent |
--如果不指定该选项,那么对话框默认显示在根窗口上 --如果想要将对话框显示在子窗口w上,那么可以设置parent=w |
title |
--指定颜色选择器标题栏的文本 --默认标题是“颜色” |
函数返回值
1. 如果用户点击的 ‘确定’ 按钮,返回值是一个二元组 (triple, color),其中的 triple 是一个三元组 (R, G, B)--其中 R, G, B 的范围是 [0, 255](就是该颜色的 RGB 颜色),第二个参数选中颜色的 16 进制的值
2. 如果用户点击的 ‘取消’ 按钮,返回值是(None, None)
例、自由绘画,可以选择颜色
import tkinter as tk
from tkinter.colorchooser import *
# 创建颜色选择函数
def colorselect():
global color # 设置全局变量
colors = askcolor()
# 设置color的颜色(R, G, B), 因为在后面会传入只能传入整数,所以这里利用int() 进行四舍五入
color = (int(colors[0][0]),int(colors[0][1]),int(colors[0][2]))
choosedcolor.set(str(color)) # 设置choosedcolor 变量的值
# 创建绘制函数
def paint(event):
x1, y1 = event.x, event.y
x2, y2 = event.x, event.y
w.create_oval(x1, y1, x2, y2, fill='#%02x%02x%02x' %color, outline='#%02x%02x%02x' %color) # 设置颜色为colorchooser所选择的
root = tk.Tk()
color = (0,0,0)
choosedcolor = tk.StringVar()
choosedcolor.set(str(color)) # 设置初始颜色
tk.Label(root, text="自由涂鸦").pack(padx=10,pady=10)
frame1 = tk.Frame(root)
tk.Button(frame1, text="选择颜色", relief='flat',command=colorselect).pack(side='left',padx=3, pady=3)
tk.Label(frame1, textvariable=choosedcolor).pack(side='left',padx=3, pady=3)
frame1.pack(anchor='w')
w = tk.Canvas(root, width=400, height=200)
w.pack()
w.bind("
tk.Button(root, text="清除屏幕", command=(lambda a='all':w.delete(a))).pack(padx=5, pady=5)
root.mainloop()
运行之,参见下图:
event(事件)
事件(event):是指点击、按键等操作,在tkinter中,event是一个类,当某个事件发生时,生成一个event对象,不同类型的事件生成具有不同属性的event对象。
事件处理(event handler):是指在捕获到事件后,程序自动执行的操作,是回调函数(recall function)。
事件绑定(event binding):是当一个事件发生时程序能够做出响应。tkinter提供三种绑定方式:实例绑定bind(将某个事件处理绑定到某个组件上)、类绑定bind_class(将某个事件处理绑定到某类组件上)、应用绑定bind_all(将某个事件处理绑定到所有组件上)。
对每一个组件来说,可以通过bind()的方法来将自己定义的函数或方法绑定到具体的事件上,event(事件)的类型主要有
Active |
当组件的状态从“未激活”变为“激活”的时候触发该事件 |
Button |
当用户点击鼠标按键的时候触发该事件 detail部分指定是具体用哪个键: |
ButtonRelease |
当用户释放鼠标按键的时候触发该事件 在大多数情况下,比Button要更好使用,因为如果当用户不小心按下鼠标键,用户可以将鼠标移出组件再释放鼠标,从而避免不小心触发事件 |
Configure |
当组件的尺寸改变的时候触发该事件(窗口管理器触发的重绘事件,当你调整组件的尺寸或者移动应用程序,组件会和窗口一样被重绘) |
Deactivate |
当组件的状态从“激活”变为“未激活”的时候触发该事件 Destroy当组件被销毁时触发该事件 |
Enter |
当鼠标指针进入组件的时候触发该事件 注意:不是用户按下回车键(回车键是Return |
Expose |
当窗口或组件的某部分不再被覆盖的时候触发该事件 |
FocusIn |
当组件获得焦点的时候触发该事件 用户可以用Tab键将焦点转移到该组件上(需要该组件的takefocus选项为True) 你也可以调用focus_set()方法使该组件获得焦点 |
FocusOut |
当组件失去焦点的时候触发该事件 |
KeyPress |
当用户按下键盘按键的时候触发该事件 detail可以指定具体的按键,例如 KeyPress可以缩写为Key |
KeyRelease |
当用户释放键盘按键的时候触发该事件 |
Leave |
当鼠标指针离开组件的时候触发该事件 |
Map |
当组件被映射的时候触发该事件 意思是在应用程序中显示该组件的时候,例如调用get()方法 |
Motion |
当鼠标在组件内移动的时候触发该事件 |
MouseWheel |
当鼠标滚轮滚动的时候触发该事件 目前该事件仅支持Windows和Mac系统 |
Unmap |
当组件被取消映射的时候触发该事件 意思是在应用程序中不再显示该组件的时候,例如调用grid_remove()方法 |
Visibility |
当应用程序至少有一部分在屏幕中是可见的时候触发该事件 |
使用时,要特别注意大小写!
在tkinter中,事件的描述格式为:<[modifier-]-type[-detail]>,其中:
modifier:事件修饰符。如:Alt、Shit组合键和Double事件。
type:事件类型。如:按键(Key)、鼠标(Button/Motion/Enter/Leave/Relase)、Configure等。
detail:事件细节。如:鼠标左键(1)、鼠标中键(2)、鼠标右键(3)。
例、
from tkinter import *
root = Tk()
#设置窗体标题
root.title('在此窗体上单击,按下字符键试试')
#设置窗口大小和位置
root.geometry('500x300')
def callbackButton1(event):
print('点击位置:', event.x, event.y)
def callbackKey(event):
print('输入的字符:', event.char)
frame = Frame(root, width=500, height=300)
frame.bind('
frame.bind('
frame.focus_set() # 设置焦点
frame.pack()
mainloop()
运行测试之,参见下图:
当事件为
下表列举了键盘所有特殊按键的 keysym 和 keycode:
(下边按键码是对应美国标准 101 键盘的“Latin-1”字符集,键盘标准不同对应的按键码不同,但按键名是一样的)
按键名(keysym) |
按键码(keycode) |
代表的按键 |
Alt_L |
64 |
左边的 Alt 按键 |
Alt_R |
113 |
右边的 Alt 按键 |
BackSpace |
22 |
Backspace(退格)按键 |
Cancel |
110 |
break 按键 |
Caps_Lock |
66 |
CapsLock(大写字母锁定)按键 |
Control_L |
37 |
左边的 Ctrl 按键 |
Control_R |
109 |
右边的 Ctrl 按键 |
Delete |
107 |
Delete 按键 |
Down |
104 |
↓ 按键 |
End |
103 |
End 按键 |
Escape |
9 |
Esc 按键 |
Execute |
111 |
SysReq 按键 |
F1 |
67 |
F1 按键 |
F2 |
68 |
F2 按键 |
F3 |
69 |
F3 按键 |
F4 |
70 |
F4 按键 |
F5 |
71 |
F5 按键 |
F6 |
72 |
F6 按键 |
F7 |
73 |
F7 按键 |
F8 |
74 |
F8 按键 |
F9 |
75 |
F9 按键 |
F10 |
76 |
F10 按键 |
F11 |
77 |
F11 按键 |
F12 |
96 |
F12 按键 |
Home |
97 |
Home 按键 |
Insert |
106 |
Insert 按键 |
Left |
100 |
← 按键 |
Linefeed |
54 |
Linefeed(Ctrl + J) |
KP_0 |
90 |
小键盘数字 0 |
KP_1 |
87 |
小键盘数字 1 |
KP_2 |
88 |
小键盘数字 2 |
KP_3 |
89 |
小键盘数字 3 |
KP_4 |
83 |
小键盘数字 4 |
KP_5 |
84 |
小键盘数字 5 |
KP_6 |
85 |
小键盘数字 6 |
KP_7 |
79 |
小键盘数字 7 |
KP_8 |
80 |
小键盘数字 8 |
KP_9 |
81 |
小键盘数字 9 |
KP_Add |
86 |
小键盘的 + 按键 |
KP_Begin |
84 |
小键盘的中间按键(5) |
KP_Decimal |
91 |
小键盘的点按键(.) |
KP_Delete |
91 |
小键盘的删除键 |
KP_Divide |
112 |
小键盘的 / 按键 |
KP_Down |
88 |
小键盘的 ↓ 按键 |
KP_End |
87 |
小键盘的 End 按键 |
KP_Enter |
108 |
小键盘的 Enter 按键 |
KP_Home |
79 |
小键盘的 Home 按键 |
KP_Insert |
90 |
小键盘的 Insert 按键 |
KP_Left |
83 |
小键盘的 ← 按键 |
KP_Multiply |
63 |
小键盘的 * 按键 |
KP_Next |
89 |
小键盘的 PageDown 按键 |
KP_Prior |
81 |
小键盘的 PageUp 按键 |
KP_Right |
85 |
小键盘的 → 按键 |
KP_Subtract |
82 |
小键盘的 - 按键 |
KP_Up |
80 |
小键盘的 ↑ 按键 |
Next |
105 |
PageDown 按键 |
Num_Lock |
77 |
NumLock(数字锁定)按键 |
Pause |
110 |
Pause(暂停)按键 |
Print 111 |
PrintScrn |
(打印屏幕)按键 |
Prior |
99 |
PageUp 按键 |
Return |
36 |
Enter(回车)按键 |
Right |
102 |
→ 按键 |
Scroll_Lock |
78 |
ScrollLock 按键 |
Shift_L |
50 |
左边的 Shift 按键 |
Shift_R |
62 |
右边的 Shift 按键 |
Tab |
23 |
Tab(制表)按键 |
Up |
98 |
↑ 按键 |