天天看點

Python之tkinter 清單框Listbox與滾動條Scrollbar

文章目錄

        • 清單框Listbox簡介
            • selectmode的參數
        • Listbox 的初步應用
        • 建立清單框項目 insert()
        • Listbox的基本操作
          • 列出清單框的選項數量 size()
          • 選取特定索引項 selection_set()
          • 删除特定索引項
        • 傳回指定的索引項 get()
          • 傳回所選取項目的索引 curselection()
          • 檢查指定索引項是否被選取 selection_includes()
        • Listbox與事件綁定
          • 虛拟綁定應用于單選
          • 虛拟綁定應用于多選
        • 活用加入和删除項目
        • Listbox 項目的排序
        • 拖拽 Listbox 中的項目
        • 滾動條的設計

清單框Listbox簡介

  清單框(Listbox)是一個顯示一系列選項的Widget控件,使用者可以進行單項或多項的選擇

使用格式如下:

參數:

  • 第一個參數:

    父對象

    ,表示這個清單框将建立在哪一個視窗内
  • 第二個參數:

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

建立清單框項目 insert()

  可以使用insert()方法為清單框建立項目,這個方法的使用格式如下

參數:

  • 第一個參數:

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

其實也可以這樣

運作結果也是一樣的

如果有很多的項目需要插入,我們可以使用循環的方式來進行

例子

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

例子

:重新設計程式,使清單框可以多選

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

例子

:重新設計,單擊一個項目,按住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()
           

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

前面是單擊并拖拽,後面是使用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()
           

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

顯示已經在最上面了,也就是一次性在最上面插入了三個項目

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

運作結果:

選取特定索引項 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()
           

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

  如果設定兩個索引值,就表示選取區間選項,第一個參數是起始索引項,第二個參數是區間的結束索引項

例子

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar
删除特定索引項

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

  可以很自然的看到“熱幹面”選項已經不見了

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

  可以看到“熱幹面、擔擔面”兩個選項已經删除了

傳回指定的索引項 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()
           

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

我們可以結合get() 方法使用

例子

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar
檢查指定索引項是否被選取 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()
           

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

  單擊Listbox中選項時會産生虛拟的

<<ListboxSelection>>

事件,此時可以觸發

itemChanged()

方法處理此事件

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

例子

def show(event):
    # 取得所選的項目索引
    index = lb.curselection()
    # 由索引取得所選的項目,關聯到label中
    var.set(lb.get(index))
           

運作結果是一樣的

或者我們不使用虛拟綁定,直接簡單粗魯的使用單擊選項,也行

例子

運作結果是一樣的!

注意:這種方式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()
           

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

活用加入和删除項目

例子

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

程式中用到的方法

上述代碼行,可以傳回最接近y坐标在Listbox中的索引。當有單擊操作時會觸發

getIndex()

方法,第4行可以傳回目前選項的索引,在拖拽過程中會觸發

gragJob()

方法,在第7行可以傳回新選項的索引,因為在拖拽過程中,這個方法會不斷的被觸發,是以至于被觸發多少次視移動速度而定

假如移動

擔擔面

,它的索引是1, 咱們向下拖拽,整個流程如下

  • 新索引位置為2
  • 獲得索引内容 ‘面窩’,參照第27行
  • 删除新内容 ‘面窩’,參照第29行
  • 将 ‘面窩’ 内容插入在索引1的位置,相當于插入到我們移動前的位置,參照第31行
  • 這個時候把新的索引位置傳給 ‘擔擔面’ ,根據索引來變換位置,變成了2,這樣就達到了移動的目的了,參照第33行

滾動條的設計

  在預設環境中Listbox 是沒有滾動條的,但是如果選項太多,将造成部分選項無法顯示,可以将

滾動條Scrollbar

控件加入Listbox中

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

使用格式如下:

參數:

  • 第一個參數:

    父對象

    ,表示這個滾動條将建立在哪一個視窗内
  • 第二個參數:

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

運作結果:

Python之tkinter 清單框Listbox與滾動條Scrollbar

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