将 Tkinter Combobox 绑定到条目更改?
Bind Tkinter Combobox to Entry change?
我有一个 ttk.Combobox
,我的用户可以从选项的下拉列表中 select,或者手动输入一些内容。我将它绑定到 Return
,所以如果我用户在进行更改后按 return 将更新,但如果我的用户单击该框并不小心键入其他内容,则会导致错误。需要明确的是,我已经有一个绑定到新 selection 的事件,以及按下 return.
请问是否可以在焦点离开框时检查框值是否已更改,如果是,则调用函数?当我尝试 FocusOut
绑定时,每次我单击其中一个下拉菜单时,它都会调用我的函数,并且不让我 select 下拉菜单中的任何内容,所以这是行不通的。
selection.bind('<Return>', lambda event, entry=selection, row=row: update(
updated_entry=entry.get(), row=row, entry=entry))
selection.bind('<<ComboboxSelected>>', lambda event, entry=selection, row=row: update(
updated_entry=entry.get(), row=row, entry=entry))
编辑:这是一个示例代码。这样写的方式,如果用户 select 从下拉列表中选择一个项目,它会更新标签。如果用户输入内容并按下 Return,它会更新标签。但是,如果用户输入内容并单击另一个下拉菜单,则不会更新标签。
import tkinter as tk
from tkinter import ttk
def update(updated_entry, row, entry):
label = tk.Text(root, height=1, width=10)
label.insert(tk.END, updated_entry)
label.grid(row=row, column=2)
return 'break'
def gui(root):
root.geometry('300x150')
root.config(background='snow3')
for row in range(2):
options = ['test', 'test1', 'test2']
selection = tk.ttk.Combobox(root, value=options)
selection.bind('<Return>', lambda event, entry=selection, row=row: update(
updated_entry=entry.get(), row=row, entry=entry))
selection.bind('<<ComboboxSelected>>', lambda event, entry=selection, row=row: update(
updated_entry=entry.get(), row=row, entry=entry))
selection.grid(row=row, column=1)
label = tk.Text(root, height=1, width=10)
label.grid(row=row, column=2)
if __name__ == '__main__':
root = tk.Tk()
gui(root)
tk.mainloop()
ttk.Combobox
es 是 Entry
widgets, which means that you can add validation 的子class 对他们来说就像你对他们的基础 class 一样。即通过使用 validate=
和 validatecommand=
选项 Entry
s 支持。
这样做的原因是因为“验证”将允许在失去焦点时检查关联的 Combobox
的内容——即你的既定目标。这应该与您已经拥有的绑定事件处理结合使用。以下代码与您的最小可重现示例类似,说明了如何做类似的事情。
注意:这种方法还允许对用户输入的值进行一些真正的验证,以防止以后出现无效的问题。
import tkinter as tk
from tkinter import ttk
def update(updated_entry, entry):
''' Combobox change Callback. '''
entry.delete('1.0', tk.END)
entry.insert(tk.END, updated_entry)
def gui(root):
root.geometry('300x150')
root.config(background='snow3')
for row in range(2):
text = tk.Text(root, height=1, width=10) # Widget to be updated.
text.grid(row=row, column=2)
def check_okay(new_value, text=text):
update(new_value, text)
return True # Note: accepts anything.
combobox = ttk.Combobox(root, value=('test', 'test1', 'test2'),
validate='focusout',
validatecommand=(root.register(check_okay), '%P'))
combobox.grid(row=row, column=1)
combobox.bind('<Return>', lambda event, entry=combobox, text=text:
update(entry.get(), entry=text))
combobox.bind('<<ComboboxSelected>>', lambda event, entry=combobox, text=text:
update(entry.get(), entry=text))
if __name__ == '__main__':
root = tk.Tk()
gui(root)
tk.mainloop()
我有一个 ttk.Combobox
,我的用户可以从选项的下拉列表中 select,或者手动输入一些内容。我将它绑定到 Return
,所以如果我用户在进行更改后按 return 将更新,但如果我的用户单击该框并不小心键入其他内容,则会导致错误。需要明确的是,我已经有一个绑定到新 selection 的事件,以及按下 return.
请问是否可以在焦点离开框时检查框值是否已更改,如果是,则调用函数?当我尝试 FocusOut
绑定时,每次我单击其中一个下拉菜单时,它都会调用我的函数,并且不让我 select 下拉菜单中的任何内容,所以这是行不通的。
selection.bind('<Return>', lambda event, entry=selection, row=row: update(
updated_entry=entry.get(), row=row, entry=entry))
selection.bind('<<ComboboxSelected>>', lambda event, entry=selection, row=row: update(
updated_entry=entry.get(), row=row, entry=entry))
编辑:这是一个示例代码。这样写的方式,如果用户 select 从下拉列表中选择一个项目,它会更新标签。如果用户输入内容并按下 Return,它会更新标签。但是,如果用户输入内容并单击另一个下拉菜单,则不会更新标签。
import tkinter as tk
from tkinter import ttk
def update(updated_entry, row, entry):
label = tk.Text(root, height=1, width=10)
label.insert(tk.END, updated_entry)
label.grid(row=row, column=2)
return 'break'
def gui(root):
root.geometry('300x150')
root.config(background='snow3')
for row in range(2):
options = ['test', 'test1', 'test2']
selection = tk.ttk.Combobox(root, value=options)
selection.bind('<Return>', lambda event, entry=selection, row=row: update(
updated_entry=entry.get(), row=row, entry=entry))
selection.bind('<<ComboboxSelected>>', lambda event, entry=selection, row=row: update(
updated_entry=entry.get(), row=row, entry=entry))
selection.grid(row=row, column=1)
label = tk.Text(root, height=1, width=10)
label.grid(row=row, column=2)
if __name__ == '__main__':
root = tk.Tk()
gui(root)
tk.mainloop()
ttk.Combobox
es 是 Entry
widgets, which means that you can add validation 的子class 对他们来说就像你对他们的基础 class 一样。即通过使用 validate=
和 validatecommand=
选项 Entry
s 支持。
这样做的原因是因为“验证”将允许在失去焦点时检查关联的 Combobox
的内容——即你的既定目标。这应该与您已经拥有的绑定事件处理结合使用。以下代码与您的最小可重现示例类似,说明了如何做类似的事情。
注意:这种方法还允许对用户输入的值进行一些真正的验证,以防止以后出现无效的问题。
import tkinter as tk
from tkinter import ttk
def update(updated_entry, entry):
''' Combobox change Callback. '''
entry.delete('1.0', tk.END)
entry.insert(tk.END, updated_entry)
def gui(root):
root.geometry('300x150')
root.config(background='snow3')
for row in range(2):
text = tk.Text(root, height=1, width=10) # Widget to be updated.
text.grid(row=row, column=2)
def check_okay(new_value, text=text):
update(new_value, text)
return True # Note: accepts anything.
combobox = ttk.Combobox(root, value=('test', 'test1', 'test2'),
validate='focusout',
validatecommand=(root.register(check_okay), '%P'))
combobox.grid(row=row, column=1)
combobox.bind('<Return>', lambda event, entry=combobox, text=text:
update(entry.get(), entry=text))
combobox.bind('<<ComboboxSelected>>', lambda event, entry=combobox, text=text:
update(entry.get(), entry=text))
if __name__ == '__main__':
root = tk.Tk()
gui(root)
tk.mainloop()