简体   繁体   English

tkinter ttk.Combobox 下拉/展开并专注于文本

[英]tkinter ttk.Combobox dropdown/expand and focus on text

I am trying to create a searchbar using combobox in tkinter and I want that while the user is typing they can see the combobox expanded with values.我正在尝试在 tkinter 中使用组合框创建一个搜索栏,我希望在用户输入时他们可以看到组合框用值扩展。 I am able to expand the combobox but the focus on combobox entry(textbox) is lost as the combo box values are expanded.我能够扩展组合框,但是随着组合框值的扩展,对组合框条目(文本框)的关注丢失了。 I have also tried to set focus of textvariable after expanding the combobox values but still in vain.我也曾尝试在扩展组合框值后设置 textvariable 的焦点,但仍然徒劳无功。 Please provide a solution without creating classes.请在不创建类的情况下提供解决方案。

# tkinter modules
import tkinter as tk
import tkinter.ttk as ttk

win=tk.Tk()
searchVar = tk.StringVar()
searchVar.trace("w", lambda name, index, mode, searchVar=searchVar:
                    on_searchText_edit())
searchBar=ttk.Combobox(win,values=["1","2","3"],width=50,textvar=searchVar)
searchBar.grid(row=0,column=1,columnspan=2,padx=5,pady=5)

def on_searchText_edit():
    txt=searchBar.focus_get() #searchVar has the focus
    searchBar.event_generate('<Down>')
    txt.focus_set()

I believe you will need to create your own widget to accomplish this task.我相信您将需要创建自己的小部件来完成此任务。 You can use an Entry widget combined with a listbox to do this.您可以结合使用一个条目小部件和一个列表框来执行此操作。 I have put some code together that shows this concept for you.我已经将一些代码放在一起,为您展示了这个概念。 The input is case sensitive.输入区分大小写。 The code is not perfect but you can tweak it to fit your needs.该代码并不完美,但您可以对其进行调整以满足您的需要。

import tkinter as tk


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry('420x200')

        frm = tk.Frame(self)

        self.var = tk.StringVar()

        ent = tk.Entry(frm, textvariable=self.var, fg='black', bg='white')
        lst = tk.Listbox(frm, bd=0, bg='white')

        item_list = ('Big Dog', 'Big Cat', 'big bird', 'Small Bird', 'Small Fish', 'Little Insect', 'Long Snake')

        ent.grid(sticky=tk.EW)
        frm.grid(sticky=tk.NW)

        def get_input(*args):
            lst.delete(0, tk.END)
            string = self.var.get()

            if string:
                for item in item_list:
                    if item.startswith(string):
                        lst.insert(tk.END, item)
                        lst.itemconfigure(tk.END, foreground="black")

                for item in item_list:
                    if item.startswith(string):
                        lst.grid(sticky=tk.NSEW)
                    elif not lst.get(0):
                        lst.grid_remove()
            else:
                lst.grid_remove()

        def list_hide(e=None):
            lst.delete(0, tk.END)
            lst.grid_remove()

        def list_input(_):
            lst.focus()
            lst.select_set(0)

        def list_up(_):
            if not lst.curselection()[0]:
                ent.focus()
                list_hide()

        def get_selection(_):
            value = lst.get(lst.curselection())
            self.var.set(value)
            list_hide()
            ent.focus()
            ent.icursor(tk.END)

        self.var.trace('w', get_input)

        ent.bind('<Down>', list_input)
        ent.bind('<Return>', list_hide)

        lst.bind('<Up>', list_up)
        lst.bind('<Return>', get_selection)


def main():
    app = App()
    app.mainloop()


if __name__ == '__main__':
    main() 

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

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