Python之tkinter 列表框Listbox与滚动条Scrollbar

列表框Listbox简介

  列表框(Listbox)是一个显示一系列选项的Widget控件,用户可以进行单项或多项的选择

使用格式如下:

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

参数:

  • 第一个参数:父对象,表示这个列表框将建立在哪一个窗口内
  • 第二个参数:options,参数如下
参数 含义
borderwidth 边界宽度
默认是两个像素
bd 边界宽度
默认是两个像素
background 背景色彩
bg 背景色彩
cursor 当鼠标光标移至列表框上时的形状
foreground 前景色彩
fg 前景色彩
font 字形
height 高,单位是字符,默认是10
highlightcolor 当列表框取得焦点时的颜色
highlightthinckness 当列表框取得焦点时的厚度
listvariable 以变量方式处理选项内容
relief 可由此控制列表框外框
默认是SUNKEN
selectbackground 被选取字符串的背景色彩
selectmode 可以决定有多少个选项可以被选,以及鼠标拖拽如何影响选项
width 宽,单位是字符宽
xscrollcommand 在X轴使用滚动条
yscrollcommand 在Y轴使用滚动条
selectmode的参数
参数 含义
BROWSE 这是默认值,我们可以选择一个选项,如果选取一个选项同时拖拽鼠标,将造成选项最后的位置是被选取的项目位置
SINGLE 只能选择一个选项,可以用单击方式选取,不可用拖拽方式更改所选的项目
MULTIPLE 可以选择多个选项,单击项目可以切换是否选择该项目
EXTENDED 单击第一个项目然后拖拽到最后一个项目,即可选择这个区间的一系列选项。
单击可以选择第一个项目,此时若是按住Shift键并单击另一个项目,可以选取区间项目

Listbox 的初步应用

例子

import tkinter

root = tkinter.Tk()
root.geometry("300x180")

# 建立listbox1
listbox1 = tkinter.Listbox(root)
listbox1.pack(side=tkinter.LEFT, padx=5, pady=5)
# 建立listbox2
listbox2 = tkinter.Listbox(root, height=5, relief='raised')
listbox2.pack(anchor=tkinter.N, side=tkinter.LEFT, padx=5, pady=5)

root.mainloop()

运行结果:
在这里插入图片描述

建立列表框项目 insert()

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

insert(index, elements)

参数:

  • 第一个参数:父index,是项目插入的位置,如果是插在最后面可以使用END
  • 第二个参数:elements,插入的字符串

例子

import tkinter

root = tkinter.Tk()

# 建立listbox1
listbox1 = tkinter.Listbox(root)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
listbox1.insert(tkinter.END, 'abc')
listbox1.insert(tkinter.END, '123')
listbox1.insert(tkinter.END, '!$#')

root.mainloop()

运行结果:
在这里插入图片描述
其实也可以这样

listbox1.insert(tkinter.END, 'abc', '123', '!$#')

运行结果也是一样的

如果有很多的项目需要插入,我们可以使用循环的方式来进行

例子

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)
root.mainloop()

运行结果:
在这里插入图片描述
例子:重新设计程序,使列表框可以多选

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.MULTIPLE)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)
root.mainloop()

运行结果:
在这里插入图片描述
例子:重新设计,单击一个项目,按住Shift可以选择一个区间内的项目

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)
root.mainloop()

运行结果:
在这里插入图片描述
前面是单击并拖拽,后面是使用Shift键选择一个区间内的项目

使用insert(ACTIVE, elements),表示是在目前选项前面加入一个项目,如果尚未选择选项则此ACTIVE是0

例子:使用ACTIVE

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)
listbox1.insert(tkinter.ACTIVE, '豆皮', '牛肉面', '汤圆')
root.mainloop()

运行结果:
在这里插入图片描述

显示已经在最上面了,也就是一次性在最上面插入了三个项目

Listbox的基本操作

下面是一些常用的Listbox 控件操作的方法

操作方法 含义
size() 传回列表项目的数量
selection_set() 选取特定索引项
delete() 删除特定索引项
get() 传回指定索引项
curselection() 传回选取项目的索引
selection_include() 检查指定索引是否被选取
列出列表框的选项数量 size()

例子

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)
print('数量是:', listbox1.size())
root.mainloop()

运行结果:

数量是: 12
选取特定索引项 selection_set()

  如果selection_set() 方法内含一个参数,表示选取这个索引项,这个功能常被用于在建立Listbox 后,设定初次选择的项目,通俗易懂的说,就是一进去默认选的是哪一个

例子

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)

# 这里设置默认选定的索引项
listbox1.select_set(1)
root.mainloop()

运行结果:
在这里插入图片描述
  如果设置两个索引值,就表示选取区间选项,第一个参数是起始索引项,第二个参数是区间的结束索引项

例子

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)

# 这里设置默认选定的索引项
listbox1.select_set(1, 3)
root.mainloop()

运行结果:
在这里插入图片描述

删除特定索引项

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

例子

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)

# 这里设置删除选定的索引项
listbox1.delete(0)
root.mainloop()

运行结果:
在这里插入图片描述
  可以很自然的看到“热干面”选项已经不见了

  如果delete() 有两个参数是,表示选取区间选项,第一个参数是区间的起始索引项,第二个参数是区间的结束索引项

例子

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)

# 这里设置删除选定的索引项
listbox1.delete(0, 1)
root.mainloop()

运行结果:
在这里插入图片描述
  可以看到“热干面、担担面”两个选项已经删除了

传回指定的索引项 get()

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

例子

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)

print(listbox1.get(1))
root.mainloop()

运行结果:

担担面

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

例子

import tkinter

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)

print(listbox1.get(1, 3))
root.mainloop()

运行结果:

('担担面', '炸酱面', '面窝')
传回所选取项目的索引 curselection()

  注意!注意!是索引,不是索引项

例子

import tkinter

def show():
    index = listbox1.curselection()
    print(index)

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)

button = tkinter.Button(root, text='print', command=show)
button.pack()
root.mainloop()

运行结果:
在这里插入图片描述

我们可以结合get() 方法使用

例子

def show():
    index = listbox1.curselection()
    for i in index:
        print(listbox1.get(i))

运行结果:
在这里插入图片描述

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

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

例子

import tkinter

def show():
    # 检查第二个选项有无被选取
    print(listbox1.select_includes(1))

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆', '混沌', '糊汤粉', '饺子', '豆皮', '牛肉面', '汤圆']
# 建立listbox1
listbox1 = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
listbox1.pack(padx=5, pady=5)

# 插入的位置与信息
for food in foods:
    listbox1.insert(tkinter.END, food)

button = tkinter.Button(root, text='print', command=show)
button.pack()
root.mainloop()

运行结果:
在这里插入图片描述

Listbox与事件绑定

虚拟绑定应用於单选

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

例子

import tkinter

def show(event):
    # 取得事件对象object
    object = event.widget
    # 取得所选的项目索引
    index = object.curselection()
    # 由索引取得所选的项目,关联到label中
    var.set(object.get(index))


root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆']

# 显示区
var = tkinter.StringVar()
label = tkinter.Label(root, textvariable=var)
label.pack(pady=5)

# 列表框
lb = tkinter.Listbox(root)
for i in foods:
    lb.insert(tkinter.END, i)
lb.bind("<<ListboxSelect>>", show)
lb.pack(pady=5)

root.mainloop()

运行结果:
在这里插入图片描述
  单击Listbox中选项时会产生虚拟的<<ListboxSelection>>事件,此时可以触发itemChanged()方法处理此事件

其实可以省略第四行,直接使用原先的Listbox对象也可以

例子

def show(event):
    # 取得所选的项目索引
    index = lb.curselection()
    # 由索引取得所选的项目,关联到label中
    var.set(lb.get(index))

运行结果是一样的

或者我们不使用虚拟绑定,直接简单粗鲁的使用单击选项,也行

例子

lb.bind("<Button-1>", show)

运行结果是一样的!

注意:这种方式pycharm会报错,但是依旧可以运行!

虚拟绑定应用于多选

例子

import tkinter

def show(event):
    object = event.widget
    indexs = object.curselection()
    for index in indexs:
        print(object.get(index))
    print('------------')


root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆']

# 列表框
lb = tkinter.Listbox(root, selectmode=tkinter.EXTENDED)
for i in foods:
    lb.insert(tkinter.END, i)


lb.bind("<<ListboxSelect>>", show)
lb.pack(pady=5)

root.mainloop()

运行结果:
在这里插入图片描述

活用加入和删除项目

例子

import tkinter

def add():
    varAdd = entry.get()
    if (len(varAdd.strip())) == 0:
        return
    listbox.insert(tkinter.END, varAdd)
    entry.delete(0, tkinter.END)

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


root = tkinter.Tk()
# 输入框
entry = tkinter.Entry(root)
entry.grid(row=0, column=0, padx=5, pady=5)

# 增加按钮
buttonAdd = tkinter.Button(root, text='增加', width=10, command=add)
buttonAdd.grid(row=0, column=1, padx=5, pady=5)

# 列表显示框
listbox = tkinter.Listbox(root)
listbox.grid(row=1, column=0, padx=5, pady=5)

# 删除按钮
buttonDelete = tkinter.Button(root, text='删除', width=10, command=delete)
buttonDelete.grid(row=1, column=1, padx=5, pady=5, sticky=tkinter.N)

root.mainloop()

运行结果:
在这里插入图片描述

Listbox 项目的排序

例子

import tkinter

def show():
    # 获取复选框是否勾选的值,如果勾选,值为True
    if var.get():
        # 定义排序的变量
        rebBool = True
    else:
        rebBool = False
    # 把我们列表框的几个值获取并转换成列表,方便排序
    listTem = list(listbox.get(0, tkinter.END))
    # 排序
    sortedList = sorted(listTem, reverse=rebBool)
    # 删除之前存在的列表框的值
    listbox.delete(0, tkinter.END)
    # 重新插入我们排序好的列表框的值
    for i in sortedList:
        listbox.insert(tkinter.END, i)

root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆']
listbox = tkinter.Listbox(root)
for food in foods:
    listbox.insert(tkinter.END, food)
listbox.pack(padx=10, pady=5)

# 创建排序按钮
button = tkinter.Button(root, text='排序', command=show)
button.pack(side=tkinter.LEFT, padx=10, pady=5)

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

root.mainloop()

运行结果:
在这里插入图片描述

拖拽 Listbox 中的项目

例子

import tkinter


# 处理单击选项
def show(event):
    # nearest可以传回最接近y座标在Listbox的索引
    # 传回目前选项的索引
    listbox.index = listbox.nearest(event.y)


# 处理拖拽选项
def showInfo(event):
    # 获取目前选项的新索引
    newIndex = listbox.nearest(event.y)
    # 判断,如果向上拖拽
    if newIndex < listbox.index:
        # 获取新位置的内容
        x = listbox.get(newIndex)
        # 删除新内容
        listbox.delete(newIndex)
        # 将新内容插入,相当于插入我们移动后的位置
        listbox.insert(newIndex + 1, x)
        # 把需要移动的索引值变成我们所希望的索引,达到了移动的目的
        listbox.index = newIndex
    elif newIndex > listbox.index:
        # 获取新位置的内容
        x = listbox.get(newIndex)
        # 删除新内容
        listbox.delete(newIndex)
        # 将新内容插入,相当于插入我们移动后的位置
        listbox.insert(newIndex - 1, x)
        # 把需要移动的索引值变成我们所希望的索引,达到了移动的目的
        listbox.index = newIndex



root = tkinter.Tk()
foods = ['热干面', '担担面', '炸酱面', '面窝', '油条', '豆浆']
listbox = tkinter.Listbox(root)
for food in foods:
    listbox.insert(tkinter.END, food)
    listbox.bind('<Button-1>', show)
    listbox.bind('<B1-Motion>', showInfo)
listbox.pack(padx=10, pady=5)


root.mainloop()

运行结果:
在这里插入图片描述

程序中用到的方法

nearest(event.y)

上述代码行,可以传回最接近y座标在Listbox中的索引。当有单击操作时会触发getIndex()方法,第4行可以传回目前选项的索引,在拖拽过程中会触发gragJob()方法,在第7行可以传回新选项的索引,因为在拖拽过程中,这个方法会不断的被触发,所以至于被触发多少次视移动速度而定

假如移动担担面,它的索引是1, 咱们向下拖拽,整个流程如下

  • 新索引位置为2
  • 获得索引内容 ‘面窝’,参照第27行
  • 删除新内容 ‘面窝’,参照第29行
  • 将 ‘面窝’ 内容插入在索引1的位置,相当于插入到我们移动前的位置,参照第31行
  • 这个时候把新的索引位置传给 ‘担担面’ ,根据索引来变换位置,变成了2,这样就达到了移动的目的了,参照第33行

滚动条的设计

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

注:Scrollbar控件除了可以应用在Listbox上,也可以应用在Text和Canvas上

使用格式如下:

Scrollbar(父对象, options, ...)

参数:

  • 第一个参数:父对象,表示这个滚动条将建立在哪一个窗口内
  • 第二个参数:options,参数如下
参数 含义
activebackground 当光标经过滚动条时,滚动条和方向箭头的颜色
bg 或 background 当光标没有经过滚动条时,滚动条和方向箭头的颜色
bd 或 borderwidth 边界宽度
默认是两个像素
command 滚动条移动时所触发的方法
cursor 当鼠标光标在滚动条上时的形状
highlightbackground 当滚动条没有获得焦点时的颜色
highlightcolor 当滚动条取得焦点时的颜色
highlightthinckness 当取得焦点时的厚度
默认是1
jump 每次短距离的拖拽滚动条时都会触发command的方法
如果设为1,则只有放开鼠标按键时,才会触发command的方法
默认是0
orient 可设置HORIZONTAL/VERTICAL,分别是水平轴/垂直轴
repeatdelay 可以设置按住滚动条移动的停滞时间
单位是ms
默认是300ms
takefocus 正常可以用Tab键的方式切换滚动条成为焦点
如果设置为0,则取消此设置
troughcolor 滚动条槽的颜色
width 宽,单位是字符宽

例子

import tkinter

root = tkinter.Tk()

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

# 列表动,滚动条跟着动
lb = tkinter.Listbox(root, yscrollcommand=sc.set)
for i in range(50):
    lb.insert(tkinter.END, "列表 " + str(i))
lb.pack(side=tkinter.LEFT, fill=tkinter.BOTH, expand=True)
# 滚动条动,列表跟着动
sc.config(command=lb.yview)

root.mainloop()

运行结果:
在这里插入图片描述

谢谢观看,笔者会持续更新,如有错误或者建议,请私信我

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章