简体   繁体   English

将 Tkinter Combobox 绑定到条目更改?

[英]Bind Tkinter Combobox to Entry change?

I have a ttk.Combobox that my users can select from a dropdown list of options, or manually type something in. I have it bound to Return , so that if my user presses return after making a change it will update, but if my user clicks in the box and accidentally types something else in, it will cause an error down the road.我有一个ttk.Combobox ,我的用户可以从选项下拉列表中 select ,或手动输入一些内容。我将它绑定到Return ,这样如果我的用户在进行更改后按下 return ,它将更新,但如果我的用户单击该框并意外输入其他内容,这将导致错误。 To be clear, I already have an event bound to a new selection, as well as pressing return.需要明确的是,我已经有一个绑定到新选择的事件,以及按下回车键。

I am asking if it is possible to check if the box value has been changed when focus leaves the box, and if so, then call a function?我在问是否可以在焦点离开框时检查框值是否已更改,如果是,则调用 function? When I tried a FocusOut bind, everytime I click on one of the dropdowns it calls my function and doesn't let me select anything from the dropdown, so that isn't working.当我尝试使用FocusOut绑定时,每次单击其中一个下拉菜单时,它都会调用我的 function 并且不会让我 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))

edit: Here is a sample code.编辑:这是一个示例代码。 The way this is written, if the user selects an item from the dropdown, it updates the label.这种写法,如果用户从下拉列表中选择一个项目,它会更新 label。 If the users types something in and presses Return, it updates the label.如果用户输入内容并按下 Return 键,它会更新 label。 But if the user types something in, and clicks on the other dropdown, it does not update the label.但如果用户输入内容并单击另一个下拉菜单,则不会更新 label。

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 are a subclass of Entry widgets, which means that you can add validation to them in the same manner as you would to their base class. ttk.ComboboxEntry小部件的子类,这意味着您可以像添加到它们的基础 class 一样向它们添加验证 Namely by using the validate= and validatecommand= options Entry s support.即通过使用validate=validatecommand=选项Entry的支持。

The reason to do this is because "validation" will allow the contents of the associated Combobox to be checked when it loses focus—ie your stated goal.这样做的原因是因为“验证”将允许在关联的Combobox失去焦点时检查它的内容——即你声明的目标。 This should work fine in conjunction with the bound event-handling you already have.这应该与您已经拥有的绑定事件处理一起正常工作。 The following code, which is similar to your minimal reproducible example, illustrates how do to something like that.以下代码类似于您的最小可重现示例,说明了如何处理类似的事情。

Note: This approach would also allow doing some real validation of the values the user has entered to prevent problems later on if they're invalid.注意:这种方法还允许对用户输入的值进行一些真正的验证,以防止以后在它们无效时出现问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM