Tkinter GUI编程的组件
学习GUI编程的总体步骤大致分为三步:
- 了解GUI库大致包含哪些组件,就相当于熟悉每个积木块到底是些什么东西
- 掌握容器及容器对组件进行布局的方法
- 逐个掌握各组件的用法,相当于深入掌握每个积木块的功能和用法
Tkinter的GUI组件有两个根父类,它们都直接继承了object类。 - Misc:它是所有组件的根父类
- Wm:它主要提供了一些与窗口管理器通信的功能函数
BaseWidget是所有组件的基类,它还派生了一个子类:Widget。Widget一共有四个父类,除了BaseWidget之外,还有Pack、Place和Grid,这三个父类都是布局管理器,它们负责管理所包含的组件的大小和位置。
各GUI组件的功能
Tkinter类 | 名称 | 简介 |
Toplevel | 顶层 | 容器类,可用于为其他组件提供单独的容器;Toplevel有点类似于窗口 |
Button | 按钮 | 代表按钮组件 |
Canvas | 画布 | 提供绘图功能,包括绘制直线、矩形、椭圆、多边形、位图等 |
Checkbutton | 复选框 | 可提供用户勾选的复选框 |
Entry | 单行输入框 | 用户可输入内容 |
Frame | 容器 | 用于装载其他GUI组件 |
Label | 标签 | 用于显示不可编辑的文本或图表 |
LabelFrame | 容器 | 用于显示不可编辑的文本或图标 |
Listbox | 列表框 | 列出多个选项,供用户选择 |
Menu | 菜单 | 菜单组件 |
Menubutton | 菜单按钮 | 用来包含菜单的按钮 |
OptionMenu | 菜单按钮 | Menubutton的子类,也代表菜单按钮,可通过按钮打开一个菜单 |
Message | 消息框 | 类似于标签,但可以显示多行文本 |
PanedWindow | 分区窗口 | 该容器会被划分成多个区域,每添加一个组件占一个区域,用户可通过拖动分割线来改变各区域的大小 |
Radiobutton | 单选钮 | 可供用户点选的单选钮 |
Scale | 滑动条 | 拖动滑块可设定起始值和结束值,可显示当前位置的精确值 |
Spinbox | 微调选择器 | 用户可通过该组件的向上、向下箭头选择不同的值 |
Scrolbar | 滑动条 | 用于为组件提供滚动功能 |
Text | 多行文本框 | 显示多行文本 |
下面通过一个简单的例子来创建一个窗口:
from tkinter import *
# 创建Tk对象,Tk代表窗口
root = Tk()
# 设置窗口标题
root.title('窗口标题')
# 创建Label对象,第一个参数指定该Label放入root
w = Label(root, text="Hello Tkinter!")
# 调用pack进行布局
w.pack()
# 启动主窗口的消息循环
root.mainloop()
布局管理器
Pack布局管理器
如果使用Pack布局,那么当程序向容器中添加组件时,这些组件会一次向后排列,排列方向即可是水平的,也可是垂直的。
pack()方法通常支持如下选项:
• anchor:当可用空间大于组件要求的大小时,该选项决定组件被放置在容器的何处
• expand:该bool值指定当父容器增大时是否拉伸组件
• fill:设置组件是否沿水平或垂直方向填充
• ipadx:指定组件在x方向上的内部留白
• ipady:指定组件在y方向上的内部留白
• padx:指定组件在x方向上与其他组件的间距
• pady:指定逐渐在y方向上与其他组件的间距
• side:设置组件的添加位置,可以设置为TOP、BOTTOM、LEFT或RIGHT者四个值的其中之一
Grid布局管理器
Grid把组件控件分解成一个网络进行维护,即按照行、列的方式和排列组件,组件位置由其行号和列号决定:行号相同而列号不同的几个组件会被依次上下排列,列号相同而行号不同的几个组件会被依次左右排列。
程序调用组件的grid()方法就进行Grid布局,在调用grid()方法时可传入多个选项,该方法支持的ipadx、ipady、padx、pady与pack()方法的这些选项相同;而grid()方法额外增加了如下选项:
• column:指定组件放入哪列,第一列的索引为0
• columnspan:指定组件横跨多少列
• row:指定组件放入哪行,第一行的索引为0
• sowspan:指定组件横跨多少行
• sticky:有点类似于pack()方法的anchor选项
Place布局管理器
Place布局就是其他GUI编程中的绝对布局,这种布局方法要求程序显示指定每个组件的绝对位置或相对于其他组件的位置。如果要使用Place布局,调用相应组件的place()方法即可:
• x:指定组件的X坐标,x为0代表位于最左边
• y:指定组件的Y坐标,y为0代表位于最右边
• relx:指定组件的X坐标,以父容器总宽度为单位1,该值应该在0.0~1.0之间,其中0.0代表窗口最坐标,1.0代表窗口最右边,0.5代表位于窗口中间
• rely:指定组件的Y坐标
• width:指定组件的宽度
• height:指定组件的高度
• relwidth:指定组件的宽度
• relheight:指定组件的高度
• bordermode:指定组件的宽度、高度是否计算该组件的边框宽度
事件处理
简单的事件处理
简单的事件处理可通过command选项来绑定,该选项绑定为一个函数或方法,当用户单击指定按钮时,通过该command选项绑定的函数或方法就会被触发。
事件绑定
上面的简单事件绑定方式虽然简单,但存在较大局限性:
- 程序无法为具体事件绑定事件处理方法
- 程序无法获取事件相关信息
为了弥补不足,Python所有Widget组件都提供了一个bind()方法,该方法可以为“任意”事件绑定事件处理方法。
代表Tkinter事件的字符串大致遵循如下格式:
<modifier-type-detail>
Tkinter支持的各种鼠标、键盘事件
事件 | 简介 |
鼠标按键的单击事件,detail指定哪一个鼠标键被单击。比如:鼠标左键,鼠标中键,鼠标右键,向上滚动的滚轮,向下滚动的滚轮 | |
鼠标在组件上的移动事件,modifier指定要求阿朱哪个鼠标键,比如:鼠标左键移动,鼠标中键移动,鼠标右键移动 | |
鼠标按键的释放事件 | |
用户双击某个鼠标键的事件 | |
鼠标进入组件的事件 | |
鼠标移出组件的事件 | |
组件及其包含的子组件失去焦点 | |
按下回车键的事件 | |
键盘上任意键的单击事件,程序可以通过event获取用户单击了哪个键 | |
a | 键盘上指定键被单击的事件 |
在Shift键被按下时按Up键 | |
组件大小、位置改变的事件 |
Tkinter常用组件
使用ttk组件
ttk作为一个模块被放在tkinter包下,使用ttk组件只要导入ttk模块即可;ttk使用功能更强大的Combobox取代了原来的Listbox,且新增了LabeledScale(带标签的Scale)、Notebook(多文档窗口)、Progressbar(进度条)、Treeview(树)等组件。
Variable类
为了让Tkinter组件与变量进行双向绑定,只要为这些组件指定variable、textvariable等属性即可,但是这种绑定只能和tkinter包下Variable类的子类进行绑定。
• StringVar():用于包装str值的变量
• IntVar():用于包装整型值的变量
• DoubleVar():用于包装浮点值的变量
• BooleanVar():用于包装bool值的变量
使用compound选项
程序为按钮或Lable等组件同时指定text和image两个选项,需要通过compound选项进行控制。
• None:图片覆盖文字
• LEFT常量:图片在左,文本在右
• RIGHT常量:图片在右,文本在左
• TOP常量:图片在上,文本在下
• BOTTOM常量:图片在底,文本在上
• CENTER常量:文本在图片上方
Entry和Text组件
Entry和Text组件都是可接受用户输入的输入框组件,Entry是单行输入框组件,Text是多行输入框组件内,而且Text可以分为不同的部分添加不同的格式,甚至响应事件。
关于Entry和Text支持的所有需要说明一下,由于Entry是单行文本框组件,因此它的所以很简单,比如要指定第4个字符到第8个字符,索引指定为(3,8)即可。但Text是多行文本框组件,因此需要同时指定行号和列号,比如1,0代表第1行(行号从1开始,列号从0开始),如果要指定第2行第3列字符到第3行第7列字符,索引应指定为(2.2,3.6)
Radiobutton和Checkbutton组件
Radiobutton组件代表单选钮,该组件可以绑定一个方法或函数,当单选钮被选中时该方法或函数将会被触发。
Checkbutton与Radiobutton相似,只是Checkbutton允许选择多项,而每组Radiobutton只能选择一项。
Listbox和Combobox组件
Listbox代表一个列表框,用户可通过列表框来选择一个列表项。ttk模块下的Combobox则是Listbox的改进版,它既提供了单行文本框让用户直接输入,也提供了下拉列表框供用户选择,因此成为复合框。
程序创建Listbox需要两步:
- 创建Listbox对象,并为之执行各种选项;
- 调用Listbox的insert(self,index,*elements)方法来添加选项
除了最常见的insert()方法,Listbox还支持如下方法:
• selection_set(self,first,last=None):选中从first到last的所有列表项
• selection_clear(self,first,last=None):取消选中从first到last的所有列表项
• delete(self,first,last=None):删除从first到last的所有列表项
Spinbox组件
Spinbox组件是一个带有两个小箭头的文本框,用户既可以通过两个小箭头上下调整该组件内的值,也可以直接在文本框内输入内容作为该组件的值。
Scale和LabeledScale组件
Scale组件代表一个滑动条,可以为该滑动条设置最小值和最大值,也可以设置滑动条每次调节的步长
• from:设置该Scale的最小值
• to:设置该Scale的最大值
• resolution:设置该Scale滑动时的步长
• label:为Scale组价设置标签内容
• length:设置轨道的长度
• width:设置轨道的宽度
• troughcolor:设置轨道的背景色
• sliderlength:设置滑块的长度
• sliderrelief:设置滑块的立体样式
• showvalue:设置是否显示当前值
• orient:设置方向
• digits:设置有效数字至少要有几位
• variable:用于与变量进行绑定
• command:用于为该Scale组件绑定事件处理函数或方法
Labelframe组件
Labelframe是Frame容器的改进版,允许为容器添加一个标签,该标签可以是普通的文字标签,也可以将任意GUI组件作为标签
Panedwindow组件
Panedwindow是一个管理窗口布局的容器,它允许添加多个子组件并未每个子组件划分一个区域,用户可用鼠标移动各区域的分割线来改变各子组件的大小。
• add(self,child,**kw):添加一个子组件
• insert(self,pos,child,**kw):在pos位置插入一个子组件
• remove(self,child):删除一个子组件
OptionMenu组件
OptionMenu组件用于构建一个带菜单的按钮,该菜单可以在按钮的四个方向上展开,使用OptionMenu比较简单,直接调用它的如下构造函数既可:
__init__(self,master,variable,value,*values,**kwargs)
- variable:指定该按钮上的菜单与哪个变量绑定
- value:指定默认选择菜单中的哪一项
- values:Tkinter将收集为此参数传入的多个值,为每个值创建一个菜单项
- kwargs:用于为OptionMenu配置选项
对话框
普通对话框
Tkinter在simpledialog和dialog模块下分别提供了SimpleDialog类和Dialog类,都可以作为普通对话框使用
在使用simpledialog.SimpleDialog创建对话框时,可指定如下选项:
• title:指定该对话框的标题
• text:指定该对话框的内容
• button:指定该对话框下方的几个按钮
• default:指定该对话框中默认第几个按钮得到焦点
• cancel:指定当用户通过对话框右上角的X按钮关闭对话框时,该对话框的返回值
如果使用dialog.Dialog创建对话框,除可使用master指定对话框的属主窗口之外,还可通过dict来指定如下选项:
• title:指定该对话框的标题
• text:指定该对话框的内容
• strings:指定该对话框下方的几个按钮
• default:指定该对话框中默认第几个按钮得到焦点
• bitmap:指定该对话框上的图标
自定义模式、非模式对话框
如果开发者需要使用自定义的对话框,包括定制模式和非模式行为,可通过继承Toplevel来实现,有两点要注意:
- 继承Toplevel来实现自定义对话框通用需要为对话框指定master
- 程序可调用Toplevel的grab_set()方法让该对话框编程模式对话框,否则就是非模式对话框
输入对话框
在simpledialog模块下还有如下便捷的工具函数,可以生产各种输入对话框:
• askinteger:生成一个让用户输入整数的对话框
• askfloat:生成一个让用户输入浮点数的对话框
• askstring:生成一个让用户输入字符的对话框
文件对话框
在filedialog模块下提供了各种用于生成文件对话框的工具函数:
• askopenfile():生成打开单个文件的对话框,返回所选择文件的文件流,可以通过该文件流来读取文件内容
• askopenfiles():生成打开多个文件的对话框,返回多个所选择文件的文件流组成的列表,可以通过这些文件流来读取文件内容
• askopenfilename():生成打开单个文件的对话框,返回所选择文件的文件路径
• askopenfilenames():生成打开多个文件的对话框,返回多个所选择文件的文件路径组成的元组
• asksaveasfilename():生成保存文件的对话框,返回所选择文件的文件路径
• askdirectory():生成打开目录的对话框
• defaultextension:指定默认扩展名
• filetypes:指定在该文件对话框中能查看的文件类型
• initialdir:指定初始打开的目录
• initiafile:指定所选择的文件
• parent:指定对话框的属主窗口
• title:指定对话框的标题
• multiple:指定是否允许多选
颜色选择对话框
在colorchooser模块下提供了用于生成颜色选择对话框的askcolor()工具函数
• parent:指定该对话框的属主窗口
• title:指定该对话框的标题
• color:指定该对话框初始选择的颜色
消息框
在messagebox模块下提供了大量工具函数来生成各种消息框。在默认的情况下,调用messagebox的工具函数只要设置提示区的字符串即可,图标区的图标、按钮区的按钮都有默认设置。
- icon:定制图标的选项,支持"error"、“info”、“question”、"warning"这几个选项值
- type:定制按钮的选项,支持"abortretryignore"(取消、重试、忽略)、“ok”(确定)、“okcancel”(确定、取消)、“retrycancel”(重试、取消)、“yesno”(是、否)、“yesnocancel”(是、否、取消)这些选项值
菜单
Tkinter为菜单提供了Menu类,搞定所有菜单相关内容。
• add_command():添加菜单项
• add_checkbutton():添加复选框菜单项
• add_radiobutton():添加单选按钮菜单项
• add_separator():添加菜单分隔条
上面的前三个方法都用于添加菜单项,因此都支持如下常用选项:
• label:指定菜单项的文本
• command:指定为菜单项绑定的事件处理方法
• image:指定菜单项的图标
• compound:指定在菜单项中图标位于文字的哪个方位
使用菜单有两种用法:
- 在窗口上方通过菜单条管理菜单
- 通过鼠标右键触发右键菜单
窗口菜单
创建菜单之后,如果要将菜单设置为窗口的菜单条,只要将该菜单设为窗口的menu选项即可。
右键菜单
实现右键菜单只需要先创建菜单,然后为目标组件的右键单击事件绑定处理函数,当用户单击鼠标右键时,调用菜单的post()方法即可在指定位置弹出右键菜单。
在Canvas中绘图
Tkinter Canvas的绘制功能
Canvas组件的用法与其他GUI组件一样简单,只要创建并添加Canvas组件,然后调用该组件的方法来绘制图形即可。Canvas提供了如下方法来绘制各种图形:
• create_rectangle():绘制矩形
• create_oval():绘制椭圆
• create_arc:绘制弧
• create_bitmap:绘制位图
• create_image:绘制图片
• create_line():绘制直线
• create_polygon:绘制多边形
• create_text:绘制文字
• create_window:绘制组件