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()

運行結果:
在這裏插入圖片描述

謝謝觀看,筆者會持續更新,如有錯誤或者建議,請私信我

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