文章目錄
列表框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()
運行結果:
謝謝觀看,筆者會持續更新,如有錯誤或者建議,請私信我