将 Tkinter 组合框绑定到条目更改? [英] Bind Tkinter Combobox to Entry change?

查看:30
本文介绍了将 Tkinter 组合框绑定到条目更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 ttk.Combobox,我的用户可以从选项下拉列表中进行选择,或者手动输入内容.我将它绑定到 Return,以便如果我的用户在进行更改后按回车键,它将更新,但如果我的用户单击该框并意外输入其他内容,则会导致错误.需要明确的是,我已经有一个绑定到新选择的事件,以及按下回车键.

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. To be clear, I already have an event bound to a new selection, as well as pressing return.

我在问是否可以检查当焦点离开框时框值是否已更改,如果是,则调用函数?当我尝试 FocusOut 绑定时,每次我单击其中一个下拉列表时,它都会调用我的函数,并且不允许我从下拉列表中选择任何内容,因此无法正常工作.

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? 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.

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 键,它会更新标签.但是如果用户输入内容并点击另一个下拉菜单,它不会更新标签.

edit: Here is a sample code. The way this is written, if the user selects an item from the dropdown, it updates the label. If the users types something in and presses Return, it updates the label. But if the user types something in, and clicks on the other dropdown, it does not update the 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.Comboboxes 是 Entry 小部件,这意味着您可以添加 validation 以与他们的基类相同的方式.即通过使用 validate=validatecommand= 选项 Entry 的支持.

ttk.Comboboxes 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. Namely by using the validate= and validatecommand= options Entrys support.

这样做的原因是因为验证"将允许在失去焦点时检查关联的 Combobox 的内容 - 即你的既定目标.这应该与您已有的绑定事件处理结合使用.以下代码与您的最小可重现示例类似,说明了如何处理类似的事情.

The reason to do this is because "validation" will allow the contents of the associated Combobox to be checked when it loses focus—i.e. your stated goal. 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()

这篇关于将 Tkinter 组合框绑定到条目更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆