十二、列表框List与滚动条Scroller

建立列表框

它的使用格式如下。

Listbox(父对象,options,···)

List()方法的第一个参数是父对象,表示这个列表框将建立在哪一个父对象内。下列是Listbox()方法
内其他常用的options参数。
(1)bg或background:背景色彩。
(2)borderwidth或bd:边界宽度,默认是两个像素。
(3)cursor:当鼠标光标在列表框上时的光标形状。
(4)fg或froeground:字形色彩。
(5)font:字形。
(6)height:高,单位是字符,默认是10。
(7)highlightcolor:当列表框获得焦点时的颜色。
(8)highlightthickness:当列表框获得焦点时的厚度。
(9)listvariable:以变量方式处理选项内容。
(10)relief:默认是relief=FLAT,可由此控制列表框外框,默认是SUNKEN。
(11)selectbackground:被选取字符串的背景色彩。
(12)selectmode:可以决定由多少选项被选,以及鼠标拖拽如何影响选项。
1.BROWSE:这是默认值,我们可以选择一个选项,如果选取一个选项同时拖拽鼠标,将造成选项
最后的位置是被选取的项目位置。
2.SINGLE:只能选择一个选项,可以用单击方式选取,不可用拖拽方式更改所选的项目。
3.MULTIPLE:可以选择多个选项,单击项目可以切换是否选择该项目。
4.EXTENDED:单击第一个项目然后拖拽到最后一个项目,即可选择这个区间的一些列选项。单击
可以选择第一个项目,此时若是按住Shift键并单击另一个项目,可以选取区间项目。
(13)width:宽,单位是字符。
(14)xscrollcommand:在x轴使用滚动条。
(15)yscrollcommand:在y轴使用滚动条。

样例:建立列表框1,然后使用字符高度5建立列表框2。

from tkinter import *

root=Tk()
root.title("ch12_1")
root.geometry("300x210")

lb1=Listbox(root)
lb1.pack(side=LEFT,padx=5,pady=10)
lb2=Listbox(root,height=5,relief="raised")
lb2.pack(anchor=N,side=LEFT,padx=5,pady=10)

root.mainloop()
image.png

建立列表框项目insert()

可以使用insert()方法为列表框建立项目,这个方法的使用格式如下。
insert(index,elements)

上述index是项目插入位置,如果是插在最后面可以使用END。

样例:建立列表框,同时为这个列表框建立Banana、Watermelon、Pineapple三个项目。

from tkinter import *

root=Tk()
root.title("ch12_2")
root.geometry("300x210")

lb=Listbox(root)
lb.insert(END,"Banana")
lb.insert(END,"Watermelon")
lb.insert(END,"Pineapple")
lb.pack(pady=10)

root.mainloop()
image.png

如果所要建立的项目很多时,建议使用list方式先储存项目,然后使用for···in循环方式将list
内的列表项目插入到列表框。

样例2:使用Listbox()构造方法时增加selectmode=MULTIPLE参数设置,这个设置可以让
用户选取多个项目。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_3")
root.geometry("300x210")

lb=Listbox(root,selectmode=MULTIPLE)
for fruit in fruits:
    lb.insert(END,fruit)

lb.pack(pady=10)

root.mainloop()
image.png

如果使用selectmode=EXTENDED参数,此时可以使用拖拽的方式选择区间项目。如果先单击
一个项目,然后按住Shift键并单击另一个项目可以选取这个区间内的项目。

目前插入选项皆是插在最后面,所以语法是insert(END,elements),其实第一个参数是索引值,
如果将END改为ACTIVE,表示是在目前选项前面加入一个项目,如果尚未选择则此ACTIVE是0。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple"]

root=Tk()
root.title("ch12_3")
root.geometry("300x210")

lb=Listbox(root,selectmode=EXTENDED)
for fruit in fruits:
    lb.insert(END,fruit)
lb.insert(ACTIVE,"Orange","Grapes","Mango")
lb.pack(pady=10)

root.mainloop()
image.png

Listbox的基本操作

Listbox的基本操作

本节将介绍下列常用的Listbox控件操作的方法。
(1)size():传回列表项目的数目。
(2)select_set():选取特定索引项。
(3)delete():删除特定索引项。
(4)get():传回指定索引项。
(5)curselection():传回选取项目的索引。
(6)selection_include():检查指定索引是否被选取。

列出列表框的选项数量size()

这个方法可以列出选项数目。

样例:建立列表框,然后列出列表框中的项目数量。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_7")
root.geometry("300x210")

lb=Listbox(root,selectmode=EXTENDED)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=10)
print("items数字:",lb.size())

root.mainloop()
image.png

选取特定索引项selection_set()

如果selection_set方法内含一个参数,表示选取这个索引项,这个功能常被用于建立好
Listbox后,设定初次选择的项目。

样例:建立一个Listbox,然后设定初次的选择项目是索引为0的项目。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_8")
root.geometry("300x210")

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=10)
lb.selection_set(0)
root.mainloop()
image.png

如果在selection_set()方法内有两个参数时,则表示选取区间选项,第一个参数是区间的起始
索引项,第二个参数是区间的结束索引项。

样例二,建立一个Listbox,然后设定初次的选择项目是索引为0~3的项目。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_8")
root.geometry("300x210")

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=10)
lb.selection_set(0,3)
root.mainloop()
image.png

删除特定索引项delete()

如果delete()方法内含有一个参数,表示删除这个索引项。

样例:建立Listbox后删除索引为1的项目,原先索引为1的项目是Watermelon,经
执行后将没有显示,因为已经被删除了。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_10")
root.geometry("300x210")

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=10)
lb.delete(1)

root.mainloop()

如果在delete()方法内有两个参数时,则表示删除区间选项,第一个参数是区间的起始索引项,
第二个参数是区间的结束索引项。

样例2:建立一个Listbox,然后删除索引为1~3的项目。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_10")
root.geometry("300x210")

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=10)
lb.delete(1,3)

root.mainloop()

传回指定的索引项get()

如果get()方法内含一个参数,表示传回这个索引项的元素内容。

样例:建立Listbox后,传回索引为1的项目。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_12")
root.geometry("300x210")

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=10)
print(lb.get(1))

root.mainloop()

如果在get()方法内有两个参数时,则表示传回区间选项,第一个参数,是区间的起始
索引项,第二个参数是区间的结束索引项,所传回的值用元组方式传回。

from tkinter import *
fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_12")
root.geometry("300x210")

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=10)
print(lb.get(1,3))

root.mainloop()

传回所选取项目的索引curselection()

这个方法会传回所选取项目的索引。

样例:建立列表框,当选取项目时,若单击Print按钮可以在Python Shell窗口中
打印所选取的内容。如果所选取项目超过两个会用元组传回。

from tkinter import *
def callback():
    indexs=lb.curselection()
    for index in indexs:
        print(lb.get(index))

fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_14")
root.geometry("300x250")

lb=Listbox(root,selectmode=MULTIPLE)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=5)
btn=Button(root,text="Print",command=callback)
btn.pack(pady=5)
root.mainloop()

检查指定索引项是否被选取selection_includes()

如果指定索引项被选取会传回True,否则传回False。

样例:检查索引3的项目是否被选取,如果被选取单击Check按钮可以显示True,
否则显示False。

from tkinter import *
def callback():
    print(lb.selection_includes(3))

fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_15")
root.geometry("300x250")

lb=Listbox(root,selectmode=MULTIPLE)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(pady=5)
btn=Button(root,text="Check",command=callback)
btn.pack(pady=5)
root.mainloop()

Listbox与事件绑定

虚拟绑定应用于单选

当Listbox执行选取操作时会产生<<ListboxSelect>>虚拟事件,可以由此设置事件处理程序。

样例:当选择Listbox中的项目时,可以在上方列出所选的项目。

from tkinter import *
def itemSelected(event):
    obj=event.widget
    index=obj.curselection()
    var.set(obj.get(index))

fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_16")
root.geometry("300x250")

var=StringVar()
lab=Label(root,text="",textvariable=var)
lab.pack(pady=5)

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
lb.bind("<<ListboxSelect>>",itemSelected)
lb.pack(pady=5)

root.mainloop()

当单击Listbox中选项时会产生虚拟的<<ListboxSelect>>事件,此时可以触发
itemChanged()方法处理此事件。itemSelected函数将所选择的内容在上方的标签中
显示。event.widget先取得事件对象obj,此例这个对象就是Listbox对象,然后利用
这个obj对象取得所选的项目索引,再由索引取得所选的项目。当然也可以省略obj=event.widget
这一行,直接使用原先的Listbox对象lb也可以。

在设计这类程序时,由于单击是被tkinter绑定选取Listbox的项目,就用双击<Double-Button-1>
方式处理,将所选项目放在标签上。

lb.binde("<Double-Button-1>",itemSelected)

虚拟绑定应用于多选

虚拟绑定的概念也可以应用于多选,下面将直接以实例讲解。

样例:当选择多项时,这些被选的项目将被打印出来。这个程序的selectmode使用
EXTENDED。

from tkinter import *
def itemSelected(event):
    obj=event.widget
    indexs=obj.curselection()
    for index in indexs:
        print(obj.get(index))
    print("---------------------")

fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_16")
root.geometry("300x250")

var=StringVar()
lab=Label(root,text="",textvariable=var)
lab.pack(pady=5)

lb=Listbox(root,selectmode=EXTENDED)
for fruit in fruits:
    lb.insert(END,fruit)
lb.bind("<<ListboxSelect>>",itemSelected)
lb.pack(pady=5)

root.mainloop()

活用加入和删除项目

本节将以一个比较实用的例子说明加入与删除Listbox项目的应用。

样例:增加与删除项目的操作。这个程序有4个Widget控件,Entry是输入控件,
可以在此输入项目,输入完项目后单击"增加"按钮,Entry中的项目就会被加入Listbox,
同时Entry将被清空。若是选择Listbox内的项目后再单击"删除"按钮,可以将所选的
项目删除。

from tkinter import *
def itemAdded():
    varAdd=entry.get()
    if (len(varAdd.strip())==0):
        return
    lb.insert(END,varAdd)
    entry.delete(0,END)

def itemDeleted():
    index=lb.curselection()
    if (len(index)==0):
        return
    lb.delete(index)

root=Tk()
root.title("ch12_19")

entry=Entry(root)
entry.grid(row=0,column=0,padx=5,pady=5)

btnAdd=Button(root,text="增加",width=10,command=itemAdded)
btnAdd.grid(row=0,column=1,padx=5,pady=5)

lb=Listbox(root)
lb.grid(row=1,column=0,columnspan=2,padx=5,sticky=W)

btnDel=Button(root,text="删除",width=10,command=itemDeleted)
btnDel.grid(row=2,column=0,padx=5,sticky=W)

root.mainloop()

Listbox项目的排序

在使用Listbox时常需要处理项目排序工作,下面将以实例讲解。

样例:这个程序中单击"排序"按钮时默认是从小到大排序,若是勾选复选框再
单击"排序"按钮将从大到小排序。

from tkinter import *
def itemsSorted():
    if (var.get()==True):
        revBool=True
    else:
        revBool=False
    listTmp=list(lb.get(0,END))
    sortedList=sorted(listTmp,reverse=revBool)
    lb.delete(0,END)
    for item in sortedList:
        lb.insert(END,item)

fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_20")

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
lb.pack(padx=10,pady=5)

btn=Button(root,text="排序",width=10,command=itemsSorted)
btn.pack(side=LEFT,padx=10,pady=5)

var=BooleanVar()
cb=Checkbutton(root,text="从大到小排序",variable=var)
cb.pack(side=LEFT)

root.mainloop()

拖拽Listbox中的项目

在建立Listbox的过程中,另一个很重要的应用是可以拖拽选项,下面将以实例讲解
这方面的应用。

样例:先建立Listbox,然后可以拖拽所选的项目。

from tkinter import *
def getIndex(event):
    lb.index=lb.nearest(event.y)

def dragJob(event):
    newIndex=lb.nearest(event.y)
    if newIndex < lb.index:
        x=lb.get(newIndex)
        lb.delete(newIndex)
        lb.insert(newIndex+1,x)
        lb.index=newIndex
    elif newIndex > lb.index:
        x=lb.get(newIndex)
        lb.delete(newIndex)
        lb.insert(newIndex-1,x)
        lb.index=newIndex

fruits=["Banana","Watermelon","Pineapple",
        "Orange","Grapes","Mango"]

root=Tk()
root.title("ch12_21")

lb=Listbox(root)
for fruit in fruits:
    lb.insert(END,fruit)
    lb.bind("<Button-1>",getIndex)
    lb.bind("<B1-Motion>",dragJob)

lb.pack(padx=10,pady=10)

root.mainloop()

这个程序中使用了下列方法:
nearest(event.y)

上述代码可以传回最接近y坐标在Listbox中的索引。当有单击操作时会触发getIndex()方法,
lb.nearest(event.y)可以传回目前选项的索引。在拖拽过程中会触发dragJob()方法,在
newIndex=lb.nearest(event.y)可以传回新选项的索引,在拖拽过程中这个方法会不断地
被触发,至于被触发多少次视移动速度而定。

滚动条的设计

在默认的环境中Listbox是没有滚动条的,但是如果选项太多,将造成部分选项无法显示,此时
可将移动滚动条Scrollbar控件加入Listbox。

注:Scrollbar控件除了可以应用在Listbox上,也可以应用在Text和Canvas控件上。
它的使用格式如下:
Scrollbar(父对象,options,···)

Scrollbar()方法的第一个参数是父对象,表示这个滚动条将建立在哪一个窗口内。下列是
Scrollbar()方法内其他常用的options参数。
(1)activebackground:当光标经过滚动条时,滚动条和方向箭头的颜色。
(2)bg或background:当光标没有经过滚动条时,滚动条和方向箭头的颜色。
(3)borderwidth或bd:边界宽度,默认是两个像素。
(4)command:滚动条移动时所触发的方法。
(5)cursor:当鼠标光标在滚动条上时的光标形状。
(6)elementborderwidth:滚动条和方向箭头的外部宽度,默认是1.
(7)highlightborderwidht:当滚动条没有获得焦点时的颜色。
(8)highlightcorlor:当滚动条获得焦点时的颜色。
(9)highlightthickness:当获得焦点时的厚度,默认是1.
(10)jump:每次短距离地拖拽滚动条时都会触发command的方法,默认是0,如果设为1则
只有放开鼠标按键时才会触发command的方法。
(11)orient:可设置HORIZONTAL/VERTICAL分别是水平轴/垂直轴。
(12)repeatdelay:单位是ms,默认是300ms,可以设置按住滚动条移动的停滞事件。
(13)takefocus:正常可以用按Tab键的方式切换滚动条成为焦点,如果设为0则取消此设置。
(14)troughcolor:滚动条槽的颜色。
(15)width:滚动条宽,默认是16.

样例:在Listbox中创建垂直滚动条。

from tkinter import *
root=Tk()
root.title("ch12_21")

scrollbar=Scrollbar(root)
scrollbar.pack(side=RIGHT,fill=Y)

lb=Listbox(root,yscrollcommand=scrollbar.set)
for i in range(50):
    lb.insert(END,"Line "+str(i))
lb.pack(side=LEFT,fill=BOTH,expand=True)
scrollbar.config(command=lb.yview)

root.mainloop()

讲解:lb=Listbox(root,yscrollcommand=scrollbar.set)是将Listbox的选项参数
yscrollcommand设为scrollbar.set,表示将Listbox与滚动条做连动。

scrollbar.config(command=lb.yview)方法是为scrollbar对象设置选择性参数内容,
此例是设置command参数,也就是当移动滚动条时,会去执行所指定的方法,此例
是执行Listbox对象lb的yview()方法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容