《零基礎入門學習Python》第068講:GUI的終極選擇:Tkinter5
這節課的主要內容為 Listbox 元件、Scrollbar 元件 和 Scale 元件
在之前的學習中,我們已經知道了,如果說提供選項給客戶選擇,那麼有兩種情況,單選的話,我們用 Radiobutton,多選的話,用Checkbutton,如果說提供的選項非常多,比如說選擇你所在的城市,那麼全國有好幾百個城市,使用 Radiobutton 和 Checkbutton 這些元件直接導致的結果就是使用者的介面根本就不夠存放那麼多按鈕,這時候你就可以考慮使用我們今天要介紹的 Listbox 元件。
一、Listbox 元件
Listbox 是用列表框的形式給顯示出來的,並且支援滾動條操作,所以對於諸如提供大量的選項這樣的情況會更適用一些。
我們先來舉個簡單的例子:
import tkinter as tk
master = tk.Tk()
theLB = tk.Listbox (master)
theLB.pack()
master.mainloop()
執行一下:
如你所見,剛開始創建出來的時候,是空的,裡面什麼都沒有,沒有任何選項,所以我們要做的第一件事就是給它新增選項,新增選項同樣是用 insert() 方法, insert() 方法 有兩個引數,第一個引數就是新增的位置,第二個引數就是新增的內容。
import tkinter as tk master = tk.Tk() theLB = tk.Listbox (master) theLB.pack() theLB.insert(0, "Python") master.mainloop()
這就有一個選項了,我們接著新增,你這裡可以使用 "end", "end" 表示最後一個位置。
theLB.insert(0, "Python")
theLB.insert("end", "來自江南的你")
當然啦,對於特別多的選項,我們肯定不建議這樣做,我們用迴圈。
import tkinter as tk master = tk.Tk() theLB = tk.Listbox (master) theLB.pack() for item in ["雞蛋", "鴨蛋", "鵝蛋", "李狗蛋", "蛋蛋"]: theLB.insert("end", item) master.mainloop()
有插入就肯定有刪除,刪除的話,我們還是使用 delete() 方法,它有兩個引數,第一個是 起始位置,第二個是 結束位置。如果只給定一個引數的話,就是指定這個引數對應的專案。
for item in ["雞蛋", "鴨蛋", "鵝蛋", "李狗蛋", "蛋蛋"]:
theLB.insert("end", item)
theLB.delete(1)
我們經常要做的就是選中哪一個,就刪除哪一個。我們現在做一個例子,我們新增一個獨立的按鈕,作用就是刪除使用者選中的專案。
import tkinter as tk
master = tk.Tk()
theLB = tk.Listbox (master)
theLB.pack()
for item in ["雞蛋", "鴨蛋", "鵝蛋", "李狗蛋", "蛋蛋"]:
theLB.insert("end", item)
theButton = tk.Button(master, text = "刪除",\
command = lambda x = theLB : x.delete("active")) #"active"就是選中的選項
theButton.pack()
master.mainloop()
執行:
最後我們要說的就是Listbox 元件根據 selectmode 選項提供了四種不同的選擇模式:"single"(單選)、"browse"(也是單選,但拖動滑鼠或通過方向鍵可以直接改變選項)、"multiple"(多選)和 "extended"(也是多選,但需要同時按住 Shift 鍵或 Ctrl 鍵或拖拽滑鼠實現)。預設是 "browse"。
theLB = tk.Listbox (master, selectmode = "extended")
theLB.pack()
大家可以每一個都試一下,感受一下效果。
選項一多啊,麻煩事就接踵而來,比如說,你發現 Listbox 預設只能顯示 10個專案,但是你手頭有 11 個專案,那怎麼辦?
我們來試一下:
import tkinter as tk
master = tk.Tk()
theLB = tk.Listbox (master, selectmode = "extended")
theLB.pack()
for item in range(11):
theLB.insert("end", item)
master.mainloop()
只能通過滑鼠滾輪才能迫使最後一個專案現身,這樣子做往往很容易被使用者所忽略。你又沒有說下面有東西,誰知道呢?
這樣的情況,有兩種方法來解決這種尷尬。
第一個方法就是修改 height 選項。
height 選項 用法
1. 設定 Listbox 顯示的行數(不是畫素)
2. 預設值是 10
我們可以改一下:
theLB = tk.Listbox (master, selectmode = "extended", height = 11)
這樣子就沒問題了。
修改 height 選項的方法雖然可以達到我們的目的,但是如果專案太多,比如說我們要顯示 1000 個,這個方法顯然就不適用了。
還有一個更加靈活的方法 就是為 Listbox 新增滾動條。
二、Scrollbar 元件
我們接著就來談談 滾動條 元件。滾動條 雖然是一個獨立的元件存在,但它幾乎都是與其他元件配合使用。下面的例子我們演示如何使用垂直滾動條。
為了在某個元件上安裝滾動條,你必須要做兩件事:
1、設定該元件的 xscrollbarcommand 或者 yscrollbarcommand 選項為 Scrollbar 元件 的 set() 方法。
2、設定 Scrollbar 元件 的 command 選項 為該元件的 xview() 或者 yview() 方法。
說起來比較複雜,但做起來很簡單,我們先來搞個滾動條出來:
import tkinter as tk
root = tk.Tk()
sb = tk.Scrollbar(root)
sb.pack()
root.mainloop()
執行一下:
我們要把它填充到右邊的位置:
sb.pack(side = "right", fill = "y")
然後我們就來增加一個 Listbox:
import tkinter as tk
root = tk.Tk()
sb = tk.Scrollbar(root)
sb.pack(side = "right", fill = "y")
lb = tk.Listbox(root, yscrollcommand = sb.set)
for i in range(200):
lb.insert("end", i)
lb.pack(side = "left", fill = "both")
sb.config(command = lb.yview)
root.mainloop()
執行一下:
工作原理:這事實上就是一個互聯互通的過程,當用戶操作滾動條進行滾動的時候,滾動條首先響應使用者的滾動操作,接下來,通過 yview() 方法(Listbox 的內建方法),內容就會自動重新整理,然後,如果是 Listbox 藜裡面滾動,它就會呼叫 sb.set() 方法,同時修改滾動條的位置。
三、Scale 元件
既然說到滾動條,我們就來順帶說一下跟滾動條長得很相似的一個元件,叫做 Scale 元件。
我們先來看一下它是什麼樣的:
import tkinter as tk
root = tk.Tk()
tk.Scale(root).pack()
root.mainloop()
雖然它和滾動條長得像,同樣都可以滾,都有滑塊,都是條形的,但是它們的應用範圍可是不一樣的。Scale 元件主要是通過滑塊來表示某個範圍內的一個數字,你可以通過修改 選項 、設定範圍以及解析度(解析度就是指的步長)。
我們來舉個例子:
當你希望使用者輸入某個範圍內的一個數字的時候,你可能會使用Entry 元件,但是Entry 元件不能限制一個範圍,你只能給出提示,然後對得到的數字進行檢測,這樣不方便。你可以直接弄一個 Scale 元件,提供一個範圍,然後使用者就只能在這個範圍內選擇。
import tkinter as tk
root = tk.Tk()
tk.Scale(root, from_= 0, to = 52).pack()
tk.Scale(root, from_= 0, to = 200, orient = 'horizontal').pack() #orient = 'horizontal' 設定為水平,預設"vertical"是垂直
root.mainloop()
獲取滑塊當前的位置,我們使用的是 get()方法,我們增加一個按鈕,來試驗一下:
import tkinter as tk
root = tk.Tk()
s1 = tk.Scale(root, from_= 0, to = 52)
s1.pack()
s2 = tk.Scale(root, from_= 0, to = 200, orient = 'horizontal')
s2.pack()
def show():
print(s1.get(), s2.get())
tk.Button(root, text = "獲取位置", command = show).pack()
root.mainloop()
接下來,你還可以通過 resolution 選項 來控制它的步長,也就是精度;使用 tickinterval 選項 顯示刻度。
import tkinter as tk
root = tk.Tk()
tk.Scale(root, from_= 0, to = 52, tickinterval = 5, resolution = 5, length = 200).pack()
tk.Scale(root, from_= 0, to = 200, tickinterval = 10, orient = 'horizontal', length = 600).pack()
root.mainloop()
為了讓所有的刻度都能夠排列下去,我們通過 length 選項 設定 Scale 元件的長度 為 200 和 600 畫素。