五笔打字通主页
Listbox是一个显示很多选项的组件,用户可以对选项单选,多选操作。
我们以前学过单选按钮radionbutton和多选按钮checkbutton,当listbox的选择模式是单选,那listbox就类似于多个单选按钮让你选择,只不是listbox是以列表的形式来显示,同样,listbox的选择模式是多选,就类似于多个多选按钮选项让用户来选择。
我们先来了解一个创建列表的语法
Listbox(父组件,参数…..)
以下是相关的参数:
bg 或 background | 组件的背景颜色 |
borderwidth | 组件的边框宽度 |
cursor | 鼠标在组件上移动的光标样式 |
fg 或 foreground | 组件的前景颜色,字体颜色 |
font | 组件的字体 |
height | 组件的高度,单位是行数,默认是10 |
listvariable | 选项内容绑定一个变量 |
relief | 组件边框样式 |
selectbackground | 被选中行的背景颜色 |
selectforeground | 被选中行的字体颜色 |
selectmode | 选项模式:single: 单选; browse:单选,但拖动鼠标或点击方向键可改变选中选项;muiltiple: 多选;extended:多选,但需要同时按住shift键或Ctrl键或拖动鼠标来进行多选 |
takefocus | 默认为True,按Tab键可得到焦点 |
width | 列表框的宽度,单位是字符,默认为20 |
xscrollcommand | 此选项可与一个水平滚动条绑定并相联动 |
yscrollcommand | 此选项可与一个垂直滚动条绑定并相联动 |
我们先来建立2个空的列表框。
lbox1=Listbox(root) # 默认大小
lbox2=Listbox(root,width=9,height=5) # 9个字符高,5行高
from tkinter import * root=Tk() root.title('tkinter列表框') lbox1=Listbox(root) # 默认大小的列表框 lbox1.pack(side=LEFT,padx=10,pady=10) lbox1=Listbox(root,width=9,height=5) # # 9个字符高,5行高 lbox1.pack(side=LEFT,padx=10) root.mainloop()
运行结果: 丶丌皛
上面的代码只是建立空的列表,我们必须用insert方法插入一些选项。
语法:
列表组件.insert ( 序号位置,插入文本 )
所谓序号,即列表的行号,从0开始,除了数字序号外,还有特殊的行号,如最后一行的序号就是END,当某个选项被选中,那个被选中的行的序号就是ACTIVE, 如果没有项被选中,那ACTIVE就是0,如果可以多选,那么ACTIVE应该是最后一个被选中的项目的序号。
插入文本,可以一次只插入一行数据,也可以一次插入多行文本。看下面的代码,很好明白。
from tkinter import * root=Tk() root.title('tkinter列表框') lbox1=Listbox(root) # 默认大小的列表框 lbox1.pack(side=LEFT,padx=10,pady=10) lbox1.insert(END,'山东') # 末尾插入文本 lbox1.insert(1,'广东') # 序号1行插入文本 lbox1.insert(ACTIVE,'青海') # 如果没有选择项目,active为0 lbox1.insert(0,'湖南') # 序号0行插入文本 lbox1.insert(END,'北京','上海','天津') # 1次插入多行文本 tuple_a=('西藏','新疆') # 先定义一个元组 lbox1.insert(END,*tuple_a) # 插入元组 root.mainloop()
上面代码,以序号,END,ACTIVE方法插入1行或多行文本,运行结果是:
单选模式browse下选择某行:
上面代码运行后,没有任何项被选中,由于默认的选择模式是单选的browse ,只能选中某一行,用代码来选中某一行,语法:
列表框.select_set(序号)
如:
lbox1.select_set(0) # 选中第1行
lbox1.select_set(2) # 选中第2行
lbox1.select_set(END) # 选中第最后1行
对于多选模式,可以选中多行,语法:
列表框.select_set(开始序号,结束序号)
如:
lbox1.select_set(0,END) # 全选
lbox1.select_set(1,3) # 选择第1行到第4行
取消选项的选择,语法:
列表框.select_clear(序号) # 取消此序号选项的选择
列表框.select_clear(开始序号,结束序号) # 取消此2个序号之间的选项的选择
列表框的选择模式
列表框的选择模式有4个:
1. single 单选,只能用鼠标点击选择。
2. browse 也是单选,拖动鼠标或击方向键还可以改变选项
3. multiple 多选,只能用鼠标点击选择
4. extended 多选,方法1:用鼠标点击,结合按住shift键,选择连续的多行;方法2:用鼠标点击,结合按住ctrl键,选择不连续的多行;方法3:用鼠标拖动方式选择多行。
下面的代码,大家可以选择不同的选择模式,操作一下,去
感受一下不同的选择选项模式。
from tkinter import * root=Tk() root.title('tkinter列表框') lbox1=Listbox(root) # 默认大小的列表框 lbox1.grid(rowspan=4,padx=10,pady=10) # 跨4行 tuple_a=('北京','上海','天津','西藏','新疆','山东', '湖北','广东','广西','湖南','云南','香港') # 先定义一个元组 lbox1.insert(END,*tuple_a) # 插入元组 lbox1.select_set(0) def selectjob(): lbox1.select_clear(0,END) # 取消选中从0到END的所有选项的选择 if var.get()==1: lbox1.config(selectmode='single') # 单选方式1 elif var.get()==2: lbox1.config(selectmode='browse') # 单选方式2 elif var.get()==3: lbox1.config(selectmode='multiple') # 多选方式1 elif var.get()==4: lbox1.config(selectmode='extended') # 多选方式2 var=IntVar(value=2) ra1=Radiobutton(root,text='single',variable=var,value=1,command=selectjob) ra1.grid(row=0,column=1,sticky=W,padx=10) ra2=Radiobutton(root,text='browse',variable=var,value=2,command=selectjob) ra2.grid(row=1,column=1,sticky=W,padx=10) ra3=Radiobutton(root,text='multiple',variable=var,value=3,command=selectjob) ra3.grid(row=2,column=1,sticky=W,padx=10) ra4=Radiobutton(root,text='extended',variable=var,value=4,command=selectjob) ra4.grid(row=3,column=1,sticky=W,padx=10) lbox1.select_set(0) # 选择第1个选项 root.mainloop()
运行结果:
用代码来删除某一行或多行的:
删除某1行的语法是: 列表框.delete(序号)
如: lbox1.delete(4) # 删除第5行
删除多行的语法是: 列表框.dfelete(开始序号,结束序号)
如: lbox1.delete(0,END) # 删除所有的行
获取选择项的文本:
获取某1行文本的语法是: 列表框.get(序号)
如: lbox1.get(4) # 获取第5行文本
获取多行文本的语法是: 列表框.get (开始序号,结束序号)
如: lbox1.get(1,3) # 获取2行到4行的文本,返回值是元组
获取所选项目的序号索引值:
语法:列表框.curselection() # 返回值是元组
判断指定序号索引项是否被选取:
语法:selection_includes(序号) # 选中返回True,否则返回False
判断列表框组件的选项总数量:
语法:列表框.size()
下面的代码,就把上面讲解的知识来运用一下。
from tkinter import * def selectjob(): lbox1.select_clear(0,END) # 取消选中从0到END的所有选项 if var.get()==1: lbox1.config(selectmode='single') # 单选方式1 elif var.get()==2: lbox1.config(selectmode='browse') # 单选方式2 elif var.get()==3: lbox1.config(selectmode='multiple') # 多选方式1 elif var.get()==4: lbox1.config(selectmode='extended') # 多选方式2 def deljob(): a=reversed(lbox1.curselection()) # 获取选择项的序号,再倒序 for i in a: lbox1.delete(i) # 用循环方法把选择项倒序一一删除 def getjob(): a=lbox1.curselection() # 获取选择项的序号 for i in a: print(lbox1.get(i)) # 用循环方法把选择项一一输出 root=Tk() root.title('tkinter列表框') lbox1=Listbox(root,height=6) # 只显示6行的列表框 lbox1.grid(rowspan=4,padx=10,pady=10) # 跨4行 tuple_a=('北京','上海','天津','西藏','新疆','山东', '湖北','广东','广西','湖南','云南','香港') # 先定义一个元组 lbox1.insert(END,*tuple_a) # 插入元组 lbox1.select_set(0) var=IntVar(value=2) # 设第2个选项为默认选中 ra1=Radiobutton(root,text='single',variable=var,value=1,command=selectjob) # 创建单选按钮1 ra1.grid(row=0,column=1,sticky=W,padx=10) ra2=Radiobutton(root,text='browse',variable=var,value=2,command=selectjob) # 创建单选按钮2 ra2.grid(row=1,column=1,sticky=W,padx=10) ra3=Radiobutton(root,text='multiple',variable=var,value=3,command=selectjob) # 创建单选按钮3 ra3.grid(row=2,column=1,sticky=W,padx=10) ra4=Radiobutton(root,text='extended',variable=var,value=4,command=selectjob) # 创建单选按钮4 ra4.grid(row=3,column=1,sticky=W,padx=10) but1=Button(root,text=" 选项总数量 ",command=lambda:print(lbox1.size())) # 创建按钮1 but1.grid(row=4,column=0,padx=10,sticky=W+E) but2=Button(root,text="判断第3行是否选中",command=lambda:print(lbox1.selection_includes(2))) # 创建按钮2 but2.grid(row=4,column=1,padx=10,pady=5,sticky=W+E) but3=Button(root,text=" 删除2到4行 ",command=lambda:lbox1.delete(1,3)) # 创建按钮3 but3.grid(row=5,column=0,padx=10,sticky=W+E) but4=Button(root,text=" 第2个选项的文本 ",command=lambda:print(lbox1.get(1))) # 创建按钮4 but4.grid(row=5,column=1,padx=10,pady=5,sticky=W+E) but5=Button(root,text=" 删除选中项 ",command=deljob) # 创建按钮5 but5.grid(row=6,column=0,padx=10,pady=5,sticky=W+E) but6=Button(root,text=" 选中项的文本 ",command=getjob) # 创建按钮6 but6.grid(row=6,column=1,padx=10,pady=5,sticky=W+E) lbox1.select_set(0) # 选择第1个选项 root.mainloop()
运行结果:
前面4个按钮的command绑定的函数比较简单,我就直接用匿名函数,按钮5绑定函数deljob,我在函数时,是把获取的选择项序号倒序,这样做的目的,就是要先把序号大的先删除,最后才删除最序号的项,如果不这样做,先把序号小的项删除,那么删除项的后面项,由于前面的项少了一个,它们的序号都会发生变化,按程序的设计删除其实是删除了别的项。
虚拟事件:
根据我们以前学的知识,可以做到鼠标点击某一项,就立即知道点击了哪一项吗?我们想当然可以。那我们就来做一下,看看行不行。
from tkinter import * def selectjob(event): print(lbox1.curselection()) # 输出选定项的序号 root=Tk() lbox1=Listbox(root,height=6) # 只显示6行的列表框 lbox1.grid(padx=10,pady=10) tuple_a=('北京','上海','天津','西藏','新疆','山东', '湖北','广东','广西','湖南','云南','香港') # 先定义一个元组 lbox1.insert(END,*tuple_a) # 插入元组 lbox1.bind("<Button-1>",selectjob) # 绑定鼠标单击 # lbox1.bind("<Double-Button-1>",selectjob) # 绑定鼠标双击 root.mainloop()
运行结果:
当你鼠标单击第1,第2,第3项时,会输出(), (0,), (1,) ,你会发现第1次是输入一个空元组,第后面的鼠标单击都是输出前1次的选定项,这明显是不正确的。
你把鼠标单击绑定代码注释掉,再绑定鼠标双击试一下。
lbox1.bind("<Double-Button-1>",selectjob) # 绑定鼠标双击
你发现,鼠标双击实现了功能,只是用鼠标双击来实现并不完美,我们希望只要点击一下就可以得到选定的项的序号,怎么办?我们以前学的都是鼠标事件,键盘事件,以及组件大小,状态变化事件好像都不能完美实现。
tkinter为此提出一个虚拟事件的概念,你可以只要用bind方法绑定它,就可以实现鼠标单击就可以得到选定项的序号。这个虚拟事件就是:<<ListboxSelect>>
虚拟事件,是用双尖括号框起来。用下面的代码代替前面的绑鼠标单击事件。
lbox1.bind("<<ListboxSelect>>",selectjob) # 绑定虚拟选定事件
再测试一下,肯定可以实现我们想要的单击选定功能。全部代码如下,大家再试试。
from tkinter import * def selectjob(event): print(lbox1.curselection()) # 输出选定项的序号 print(lbox1.get(lbox1.curselection())) # 输出选定项的文本 root=Tk() lbox1=Listbox(root,height=6) # 只显示6行的列表框 lbox1.grid(padx=10,pady=10) tuple_a=('北京','上海','天津','西藏','新疆','山东', '湖北','广东','广西','湖南','云南','香港') # 先定义一个元组 lbox1.insert(END,*tuple_a) # 插入元组 lbox1.bind("<<ListboxSelect>>",selectjob) # 绑定虚拟选定事件 root.mainloop()
虚拟事件同样也可以用于listbox的多选模式,大家自己试吧。
本文章,源码来自 wb98·com
Listbox组件可以绑定滚动条,这样,文本超长的时候,就可以用滚动条来滚动查看了。
滚动条下一篇文章再讲,所以Listbox组件的xscrollcommand和xscrollcommand 这2个参数就在下篇文章再讲解了。
来源:济亨网
本文链接:http://wb86.com/post/321.html