将Tkinter组合框绑定到条目更改?



我有一个ttk.Combobox,我的用户可以从选项的下拉列表中选择,或者手动输入一些东西。我将它绑定到Return,这样如果我的用户在进行更改后按下return,它就会更新,但是如果我的用户在框中单击并意外地键入其他内容,则会导致错误。为了清楚,我已经有一个事件绑定到一个新的选择,以及按回车。

我问是否有可能检查当焦点离开框时框值是否已经改变,如果是这样,然后调用函数?当我尝试FocusOut绑定时,每次我点击其中一个下拉菜单,它调用我的函数,不让我从下拉菜单中选择任何东西,所以这是不工作的。

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))
下面是一个示例代码。它的编写方式是,如果用户从下拉菜单中选择一个项目,它就会更新标签。如果用户输入内容并按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.Comboboxe是Entry小部件的子类,这意味着您可以以与对其基类相同的方式向它们添加验证。即通过使用validate=validatecommand=选项Entry的支持。

这样做的原因是"validation"将允许在失去焦点时检查相关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()

最新更新