Tkinter: Jak zmienić zawartość jakiegoś widgeta używając wartości wybranej w Combobox?
Aby pobrać wartość wybraną w Combobox
i użyć jej do zmienienia wartości w Label
możesz użyć bind()
z (wirtualnym) zdarzeniem '<<ComboboxSelected>>'
.
Można go użyć do przypisania funkcji, która ma być wykonana zaraz po wybraniu wartości w Combobox
- i tak funkcja może zmienić wartość Label
import tkinter as tk
import tkinter.ttk as ttk
# --- functions ---
def on_select(event):
#print('[DEBUG] event:', event)
#print('[DEBUG] event.widget:', event.widget)
#print('[DEBUG] event.widget.get():', event.widget.get())
#print('---')
selected = event.widget.get()
label['text'] = selected
# --- main ---
root = tk.Tk()
combo = ttk.Combobox(root, values=['A', 'B', 'C'])
combo.pack()
combo.bind('<<ComboboxSelected>>', on_select)
label = tk.Label(root) # can be without any text or ie. with `?`
label.pack()
root.mainloop()
Najpierw tworzymy Combobox
(Nie jest istotne czy użyjemy pack()
, grid()
czy place()
)
combo = ttk.Combobox(root, values=['A', 'B', 'C'])
combo.pack()
Następnie używamy bind()
do przypisania nazwy funkcji - np. on_select
(bez ()
i bez argumentów) - do zdarzenia '<<ComboboxSelected>>'
w widgecie Combobox
combo.bind('<<ComboboxSelected>>', on_select)
I ostatecznie trzeba stworzyć wspomnianą funkcję on_select
, która pobiera jeden argument - ie. event
- z informacjami o zdarzeniu.
W zmiennej zawierajacej zdarzenie mogą być różne informacje - przykładowo event.widget
która daje dostęp do widgetu Combobox
, który był wykorzystany.
W ten sposób można przypisać tą samą funkcję do dwóch różnych Combobox
i dostać dostęp do właściwego widgetu.
def on_select(event):
#print('[DEBUG] event:', event)
#print('[DEBUG] event.widget:', event.widget)
#print('[DEBUG] event.widget.get():', event.widget.get())
#print('---')
selected = event.widget.get()
label['text'] = selected
A teraz dłuższy przykład, który używa Combobox
do zmiany zawartości Label
, Button
, Entry
, Listbox
, Text
a także w drugim Combobox
import tkinter as tk
import tkinter.ttk as ttk
# --- functions ---
def on_select(event):
print('[DEBUG] event:', event)
print('[DEBUG] event.widget:', event.widget)
print('[DEBUG] event.widget.get():', event.widget.get())
print('---')
selected = event.widget.get()
label['text'] = selected
button['text'] = selected
entry.delete('0', 'end') # remove previous content
entry.insert('end', selected)
combobox2_values = {
'A': ['A1', 'A2', 'A3'],
'B': ['B1', 'B2', 'B3'],
'C': ['C1', 'C2', 'C3'],
}
combobox2['values'] = combobox2_values[selected]
listbox.delete(0, 'end') # remove previous content
for item in combobox2_values[selected]:
listbox.insert('end', item)
values = combobox2_values[selected]
values_str = ', '.join(values)
#text.delete('1.0', 'end') # remove previous content
text.insert('end', selected + ': ' + values_str + '\n')
# --- main ---
root = tk.Tk()
combobox = ttk.Combobox(root, values=['A', 'B', 'C'])
combobox.pack()
combobox.bind('<<ComboboxSelected>>', on_select)
# --- other widgets ---
label = tk.Label(root, text='?')
label.pack()
button = tk.Button(root, text='?')
button.pack()
entry = tk.Entry(root)
entry.pack()
#entry.insert(0, '?')
#entry.insert('end', '?')
combobox2 = ttk.Combobox(root)
combobox2.pack()
listbox = tk.Listbox(root)
listbox.pack()
text = tk.Text(root, width=30, height=10)
text.pack()
#text.insert('1.0', '?\n')
#text.insert('end', '?\n')
# ---
root.mainloop()
Notatki:
-
Różne widgety mogą używać różnych zarzeń i większość z nich używa pojedynczego
< >
-
Funkcja przypisana za pomocą
bind()
jest zawsze wywoływana z informacją o zdarzeniu - tak więc musi ona pobrać tę informację - używając argumentu np. o nazwieevent
. -
Zdarzenie
<<ComboboxSelected>>
zawiera podwójne<< >>
. W niektórej dokumentacji zadrzenie z podwójnym<< >>
jest nazywanewirtaulnym zdarzenie
(virtual event
). -
Nazwa funkcji bez
()
(i bez argumentów), która jest przypisana jako argument w innej funkcji (która wywoła ją później) często jest nazywana"callback"
. Ta nazwa jest używana nie tylko wtkinter
iPython
ale także w innych modułach i innych językach. -
W
tkinter
callback jest wykorzystywany wbind(event, callback)
,after(milisekundy, callback)
,tk.Button(..., command=callback)
i w kilku innych widgetach.
Buy a Coffee