列表框(ListBox)和组合框(Combobox)
列表框(Listbox)和复选框(Combobox)是 Tkinter 中两个控件,由于其非常相似,所有将它们放在一起进行介绍。
Listbox控件
首先介绍一下列表框,即 Listbox。在使用 Tkinter 进行 GUI 编程的过程中,如果需要用户自己进行选择时就可以使用列表框控件。列表框中的选项可以是多个条目,也可以是单个唯一条目,但常用于多个条目。下面对列表框控件(Listbox)的常用方法做简单的介绍:
方法 | 说明 |
activate(index) | 将给定索引号对应的选项激活,即文本下方画一条下划线 |
bbox(index) | 返回给定索引号对应的选项的边框,返回值是一个以像素为单位的 4 元祖表示边框:(xoffset, yoffset, width, height), xoffset 和 yoffset 表示距离左上角的偏移位置 |
curselection() | 返回一个元组,包含被选中的选项序号(从 0 开始) |
delete(first, last=None) | 删除参数 first 到 last 范围内(包含 first 和 last)的所有选项 |
get(first, last=None) | 返回一个元组,包含参数 first 到 last 范围内(包含 first 和 last)的所有选项的文本 |
index(index) | 返回与 index 参数相应选项的序号 |
itemcget(index, option) | 获得 index 参数指定的项目对应的选项(由 option 参数指定) |
itemconfig(index, **options) | 设置 index 参数指定的项目对应的选项(由可变参数 **option 指定) |
nearest(y) | 返回与给定参数 y 在垂直坐标上最接近的项目的序号 |
selection_set(first, last=None) | 设置参数 first 到 last 范围内(包含 first 和 last)选项为选中状态,使用 selection_includes(序号) 可以判断选项是否被选中。 |
size() | 返回 Listbox 组件中选项的数量 |
xview(*args) | 该方法用于在水平方向上滚动 Listbox 组件的内容,一般通过绑定 Scollbar 组件的 command 选项来实现。 如果第一个参数是 "moveto",则第二个参数表示滚动到指定的位置:0.0 表示最左端,1.0 表示最右端;如果第一个参数是 "scroll",则第二个参数表示滚动的数量,第三个参数表示滚动的单位(可以是 "units" 或 "pages"),例如:xview("scroll", 2, "pages")表示向右滚动二行。 |
yview(*args) | 该方法用于在垂直方向上滚动 Listbox 组件的内容,一般通过绑定 Scollbar 组件的 command 选项来实现 |
除了共有属性之外,列表框控件也有一些其他属性,如下表所示:
属性 | 说明 |
listvariable | 1. 指向一个 StringVar 类型的变量,该变量存放 Listbox 中所有的项目 2. 在 StringVar 类型的变量中,用空格分隔每个项目,例如 var.set("c c++ java python") |
selectborderwidth | 1. 指定当某个项目被选中的时候边框的宽度 2. 默认是由 selectbackground 指定的颜色填充,没有边框 3. 如果设置了此选项,Listbox 的每一项会相应变大,被选中项为 "raised" 样式 |
selectforeground | 1. 指定当某个项目被选中的时候文本颜色,默认值由系统指定 |
selectmode | 1. 决定选择的模式,tk 提供了四种不同的选择模式,分别是:"single"(单选)、"browse"(也是单选,但拖动鼠标或通过方向键可以直接改变选项)、"multiple"(多选)和 "extended"(也是多选,但需要同时按住 Shift 键或 Ctrl 键或拖拽鼠标实现),默认是 "browse" |
setgrid | 指定一个布尔类型的值,决定是否启用网格控制,默认值是 False |
takefocus | 指定该组件是否接受输入焦点(用户可以通过 tab 键将焦点转移上来),默认值是 True |
xscrollcommand | 为 Listbox 组件添加一条水平滚动条,将此选项与 Scrollbar 组件相关联即可 |
yscrollcommand | 为 Listbox 组件添加一条垂直滚动条,将此选项与 Scrollbar 组件相关联即可 |
创建列表框控件
下面看一组简单的示例,并对 Listbox 控件做进一步讲解,首先创建一个列表框控件:
# 创建一个列表控件,并增加相应的选项 from tkinter import * # 创建主窗口 win = Tk() win.title("艾派森") win.geometry('400x200') win.iconbitmap('favicon.ico') # 创建列表选项 listbox1 =Listbox(win) listbox1.pack() # i表示索引值,item 表示值,根据索引值的位置依次插入 for i,item in enumerate(["C","C++","C#","Python","Java"]): listbox1.insert(i,item) # 显示窗口 win.mainloop()
增加滚动条和删除功能
下面为上述示例增加一个滚动条和选项的删除功能,如下所示:
from tkinter import * # 创建主窗口 win = Tk() win.title("艾派森") win.geometry('400x180') win.iconbitmap('favicon.ico') # 创建滚动条 s = Scrollbar(win) # 设置垂直滚动条显示的位置,使得滚动条,靠右侧;通过 fill 沿着 Y 轴填充 s.pack(side = RIGHT,fill = Y) # 将 selectmode 设置为多选模式,并为Listbox控件添加滚动条 listbox1 = Listbox(win,selectmode = MULTIPLE,height =5, yscrollcommand = s.set) # i 表示索引值,item 表示值,根据索引值的位置依次插入 for i,item in enumerate(range(1,50)): listbox1.insert(i,item) listbox1.pack() # 设置滚动条,使用 yview使其在垂直方向上滚动 Listbox 组件的内容,通过绑定 Scollbar 组件的 command 参数实现 s.config(command = listbox1.yview) # 使用匿名函数,创建删除函数,点击删除按钮,会删除选项 bt = Button(win,text='删除',command = lambda x = listbox1:x.delete(ACTIVE)) # 将按钮放置在底部 bt.pack(side = BOTTOM) # 显示窗口 win.mainloop()
StringVar() 添加列表选项
下面演示如何通过 StringVar() 方法动态地获取列表框中的选项,示例代码如下:
import tkinter as tk
import tkinter as tk from tkinter import messagebox window = tk.Tk() window.title("艾派森") window.geometry('400x180') window.iconbitmap('favicon.ico') # 创建变量,用var1用来接收鼠标点击的具体选项内容 var1 = tk.StringVar() l = tk.Label(window, bg='#B0B0B0', font=('微软雅黑', 15), width=20, textvariable=var1) l.pack() # 创建一个按钮的点击事件 def click_button(): # 使用 curselection来选中文本 try: val = lb.get(lb.curselection()) # 设置label值 var1.set(val) except Exception as e: e = '发现一个错误' messagebox.showwarning(e,'没有选择任何条目') # 创建一个按钮并放置,点击按钮调用print_selection函数 b1 = tk.Button(window, text='获取当前选项', command=click_button) b1.pack() # 创建Listbox并为其添加内容 var2 = tk.StringVar() var2.set(("C语言辅导班", "Python答疑辅导", "Java答疑辅导", "C++辅导")) # 创建Listbox,通过 listvariable来传递变量 lb = tk.Listbox(window, listvariable=var2) # 新建一个序列,然后将值循环添加到Listbox控件中 items = ["C", "Java", "Python", "C#", "Golang", "Runby"] for i in items: lb.insert('end', i) # 从最后一个位置开始加入值 lb.insert(0, '编程学习') # 在第一个位置插入一段字符串 lb.delete(4) # 删除第2个位置处的索引 lb.pack() #主窗显示 window.mainloop()
Combobox控件
通过前面内容的介绍我们知道 Listbox 是一个供用户从列表项中选择相应条目的控件。但在有些情况下,比如列表的项目过多时,若使用列表控件,列出所有选项就会显得界面格外臃肿,这时就需要用到 Combobox 控件,也就是下拉菜单控件(或称复合框),该控件是列表控件的改进版,具有更加灵活的界面,因此其应用场景相比于前者要更加广泛。
不过需要注意的是 Combobox 并不包含在 tkinter 模块中,而是包含在tkinter.ttk子模块中,因此若想使用 Combobox 控件,需要使用下面的导包方式:
from tkinter import ttk
Combobox 控件在形式虽然与列表控件存在不同,但它们的本质是相同,因此属性和方法是通用的。对于 Combobox 控件而言,它常用的方法有两个,分别是 get() 和 current(),前者表示获取当前选中选项的内容,后者表示获取选中选项的索引值。下面通过一组简单的示例进一步了解 Combobox 控件,示例代码如下:
import tkinter from tkinter import ttk # 导入ttk模块,下拉菜单控件位于ttk子模块中 # 创建窗口 win = tkinter.Tk() win.title("艾派森") win.iconbitmap('favicon.ico') win.geometry('400x250') win.resizable(0,0) # 创建下拉菜单 cbox = ttk.Combobox(win) # 使用 grid() 来控制控件的位置 cbox.grid(row = 1, sticky="NW") # 设置下拉菜单中的值 cbox['value'] = ('C','C#','Go','Python','Java') #通过 current() 设置下拉菜单选项的默认值 cbox.current(3) # 编写回调函数,绑定执行事件,向文本插入选中文本 def func(event): text.insert('insert',cbox.get()+"\n") # 绑定下拉菜单事件 cbox.bind("<<ComboboxSelected>>",func) # 新建文本框 text = tkinter.Text(win) # 布局 text.grid(pady = 5) win.mainloop()
单选框(Radiobutton)和多选框按钮(Checkbutton)
单选框按钮控件(Radiobutton),同样允许用户选择具体的选项值,不过与 Listbox 相比,单选按钮控件仅允许用户选择单一的选项值,各个选项值之间是互斥的关系,因此只有一个选项可以被用户选择。Radiobutton 控件通常都是成组出现的,所有控件都使用相同的变量。Radiobutton 可以包含文本或图像,每一个按钮都可以与一个 Python 函数相关联。当按钮被按下时,对应的函数会被执行。这里需要注意的是,单选按钮控件仅能显示单一字体的文本,但文本可以跨越多行,除此之外,您还可以为个别的字符添加下划线。
Radiobutton 除常用的共有属性之外,还具有一些其他属性,如下表所示:
属性 | 说明 |
activebackground | 设置当 Radiobutton 处于活动状态(通过 state 选项设置状态)的背景色,默认值由系统指定 |
activeforeground | 设置当 Radiobutton 处于活动状态(通过 state 选项设置状态)的前景色,默认值由系统指定 |
compound | 1. 默认值为 None,控制 Radiobutton 中文本和图像的混合模式,默认情况下,如果有指定位图或图片,则不显示文本 2. 如果该选项设置为 "center",文本显示在图像上(文本重叠图像) 3. 设置为 "bottom","left","right" 或 "top",那么图像显示在文本的旁边,比如如"bottom",则显示图像在文本的下方。 |
disabledforeground | 指定当 Radiobutton 不可用的时的前景色颜色,默认由系统指定 |
indicatoron | 1. 该参数表示选项前面的小圆圈是否被绘制,默认为 True,即绘制; 2. 如果设置为 False,则会改变单选按钮的样式,当点击时按钮会变成 "sunken"(凹陷),再次点击变为 "raised"(凸起) |
selectcolor | 设置当 Radiobutton 为选中状态的时候显示的图片;如果没有指定 image 选项,该选项被忽略 |
takefocus | 如果是 True,该组件接受输入焦点,默认为 False |
variable | 表示与 Radiobutton 控件关联的变量,注意同一组中的所有按钮的 variable 选项应该都指向同一个变量,通过将该变量与 value 选项值对比,可以判断用户选中了哪个按钮。 |
Radiobutton 控件的常用方法如下所示:
方法 | 说明 |
deselect() | 取消该按钮的选中状态 |
flash() | 刷新 Radiobutton 控件,该方法将重绘 Radiobutton控件若干次(即在"active" 和 "normal" 状态间切换) |
invoke() | 1. 调用 Radiobutton 中 command 参数指定的函数,并返回函数的返回值 2. 如果 Radiobutton 控件的 state(状态) 是 "disabled" (不可用)或没有指定 command 选项,则该方法无效 |
select() | 将 Radiobutton 控件设置为选中状态 |
Radiobutton 控件用来解决多选一的问题,它通常是成组出现的,下面看一组简答的示例:
import tkinter as tk window = tk.Tk() window.title("艾派森") window.geometry('400x180') window.iconbitmap('favicon.ico') # IntVar() 用于处理整数类型的变量 v = tk.IntVar() # 根据单选按钮的 value 值来选择相应的选项 v.set(0) # 使用 variable 参数来关联 IntVar() 的变量 v tk.Radiobutton(window, text="JAVA", fg='blue',font=('微软雅黑','12','bold'),variable=v, value=0).pack(anchor = 'w') tk.Radiobutton(window, text="Python", variable=v, value=1).pack(anchor = 'w') tk.Radiobutton(window, text="C++", variable=v, value=2).pack(anchor = 'w') tk.Radiobutton(window, text="Go", variable=v, value=3).pack(anchor = 'w') # 显示窗口 window.mainloop()
上述代码是比较直接的写法,虽然编码过程简单,但是从代码重构的角度来讲,它是比较冗余的,因此我们推荐下面这种写法,如下所示:
import tkinter as tk window = tk.Tk() window.title("艾派森") window.geometry('400x180') window.iconbitmap('favicon.ico') site = [('美团外卖',1), ('饿了么外卖',2), ('美团闪购',3), ('艾奇外卖',4)] # IntVar() 用于处理整数类型的变量 v = tk.IntVar() # 重构后的写法,也非常简单易懂 for name, num in site: radio_button = tk.Radiobutton(window,text = name, variable = v,value =num) radio_button.pack(anchor ='w') # 显示窗口 window.mainloop()
对上述代码稍作修改,当点击某一按钮时,获取选项的内容,代码如下:
import tkinter as tk def select(): dict = {1:'Python',2:'java',3:'c++',4:'Go'} strings = '您选择了' + dict.get(v.get()) + ',祝您学习愉快' lable.config(text = strings) window = tk.Tk() window.title("艾派森") window.geometry('400x180') window.iconbitmap('favicon.ico') lable = tk.Label(window,font=('微软雅黑', '15','bold'),fg='#43CD80') lable.pack(side ='bottom') site = [('Python',1), ('java',2), ('c++',3), ('Go',4)] # IntVar() 用于处理整数类型的变量 v = tk.IntVar() for name, num in site: radio_button = tk.Radiobutton(window,text = name, variable = v,value =num,command = select,indicatoron = False) radio_button.pack(anchor ='w') # 显示窗口 window.mainloop()
Checkbutton复选框控件
Checkbutton 控件是一种供用户选择相应条目的按钮控件,但与 Radiobutton 不同的是,Checkbutton 控件不仅允许用户选择一项,还允许用户同时选择多项,各个选项之间属于并列的关系。复选框控件同样有许多适用场景,比如选择兴趣爱好、选择选修课,以及购买多个物品等,在这种情况下都可以使用复选框控件。复选框控件,除了具有常用的共有属性之外,还具有一些其他重要属性和常用方法,下面对它们做简单地介绍:
属性 | 说明 |
text | 显示的文本,使用 "\n" 来对文本进行换行。 |
variable | 1. 和复选框按钮关联的变量,该变量值会随着用户选择行为来改变(选或不选),即在 onvalue 和 offvalue 设置值之间切换,这些操作由系统自动完成 2. 在默认情况下,variable 选项设置为 1 表示选中状态,反之则为 0,表示不选中。 |
onvalue | 通过设置 onvalue 的值来自定义选中状态的值。 |
offvalue | 通过设置 offvalue 的值来自定义未选中状态的值。 |
indicatoron | 默认为 True,表示是否绘制用来选择的选项的小方块,当设置为 False 时,会改变原有按钮的样式,与单选按钮相同 |
selectcolor | 选择框的颜色(即小方块的颜色),默认由系统指定 |
selectimage | 设置当 Checkbutton 为选中状态的时候显示的图片,若如果没有指定 image 选项,该选项被忽略 |
textvariable | Checkbutton 显示 Tkinter 变量(通常是一个 StringVar 变量)的内容,如果变量被修改,Checkbutton 的文本会自动更新 |
wraplength | 表示复选框文本应该被分成多少行,该选项指定每行的长度,单位是屏幕单元,默认值为 0 |
下面看一组简单的示例,创建一组复选框控件,代码如下:
from tkinter import * win = Tk() win.title("艾派森") win.geometry('500x200') win.resizable(0,0) lb = Label(text='编程语言答疑辅导班',font=('微软雅黑', 18,'bold'),fg='#CD7054') lb.pack() win.iconbitmap('favicon.ico') # 新建整型变量 CheckVar1 = IntVar() CheckVar2 = IntVar() CheckVar3 = IntVar() # 设置三个复选框控件,使用variable参数来接收变量 check1 = Checkbutton(win, text="Python",font=('微软雅黑', 15,'bold'),variable = CheckVar1,onvalue=1,offvalue=0) check2 = Checkbutton(win, text="C语言",font=('微软雅黑', 15,'bold'),variable = CheckVar2,onvalue=1,offvalue=0) check3 = Checkbutton(win, text="Java",font=('微软雅黑', 15,'bold'),variable = CheckVar3,onvalue=1,offvalue=0) # 选择第一个为默认选项 # check1.select () check1.pack(side = LEFT) check2.pack(side = LEFT) check3.pack(side = LEFT) # 定义执行函数 def study(): # 没有选择任何项目的情况下 if (CheckVar1.get() == 0 and CheckVar2.get() == 0 and CheckVar3.get() == 0): s = '您还没选择任语言' else: s1 = "Python" if CheckVar1.get() == 1 else "" s2 = "C语言" if CheckVar2.get() == 1 else "" s3 = "Java" if CheckVar3.get() == 1 else "" s = "您选择了%s %s %s" % (s1, s2, s3) #设置标签lb2的字体 lb2.config(text=s) btn = Button(win,text="选好了",bg='#BEBEBE',command=study) btn.pack(side = LEFT) # 该标签,用来显示选择的文本 lb2 = Label(win,text='',bg ='#9BCD9B',font=('微软雅黑', 8,'bold'),width = 8,height=2) lb2.pack(side = BOTTOM, fill = X) # 显示窗口 win.mainloop()
复选框控件提供以下常用方法,如下表所示:
方法 | 属性 |
desellect() | 取消 Checkbutton 组件的选中状态,也就是设置 variable 为 offvalue |
flash() | 刷新 Checkbutton 组件,对其进行重绘操作,即将前景色与背景色互换从而产生闪烁的效果。 |
invoke() | 1. 调用 Checkbutton 中 command 选项指定的函数或方法,并返回函数的返回值 2. 如果 Checkbutton 的state(状态)"disabled"是 (不可用)或没有指定 command 选项,则该方法无效 |
select() | 将 Checkbutton 组件设置为选中状态,也就是设置 variable 为 onvalue |
toggle() | 改变复选框的状态,如果复选框现在状态是 on,就改成 off,反之亦然 |
下面看一组简答的示例,如下所示:
from tkinter import * win = Tk() win.title("艾派森") win.geometry('500x200') win.resizable(0,0) lb = Label(text='编程语言答疑辅导班',font=('微软雅黑', 18,'bold'),fg='#CD7054') lb.pack() win.iconbitmap('favicon.ico') # 设置三个复选框控件, check1 = Checkbutton(win, text="Python",font=('微软雅黑', 15,'bold'),onvalue=1,offvalue=0) check2 = Checkbutton(win, text="C语言",font=('微软雅黑', 15,'bold'),onvalue=1,offvalue=0) check3 = Checkbutton(win, text="Java",font=('微软雅黑', 15,'bold'),onvalue=1,offvalue=0) # 将第一个 复选框按钮的 variable值,设置为 onvalue =1 ,表示选中状态 check1.select () # 取消了第一个复选框的选中状态 # check1.toggle() check1.pack (side = LEFT) check2.pack (side = LEFT) check3.pack (side = LEFT) # 显示窗口 win.mainloop()
本次关于Tkinter的知识点先分享到这,剩下的下次分享。