那麼幾件事情,我不得不改變得到這個至少一個字工作。目前,如果您希望繼續以連續字符串輸入更多單詞,它將不起作用。
我相信我終於可以得到這個工作,但我試圖回答從列表框中更新單詞並將焦點轉回到輸入字段的問題。我不得不改變幾件事情。
首先,我不得不改變:
index = int(self.dropdown.curselection()[0])
要:
index = self.dropdown.curselection()[0]
爲self.dropdown.curselection()[0]
返回值已經是一個int。不需要再次將整數作爲整數。
其次,我不得不改變:
def _add_course(self, value):
self.listbox.insert(END, value)
self.my_list.append(value)
要:
def _add_course(self, value):
self.entry.delete(0,END)
self.entry.insert(END, value)
self.my_list.append(value)
當你試圖插入的value
到列表框中沒有輸入字段。另請注意,我將self.list
更改爲self.my_list`。你應該避免命名可能覆蓋內置函數的東西。
我需要改變的最後一件事是我們如何將焦點設置回輸入字段。我相信焦點問題在於,您正在將注意力放在鼠標點擊上,但是您仍然在列表框中單擊並且正在關注焦點。我們需要爲焦點集添加延遲,以便在焦點設置到輸入字段之前,我們有時間完成鼠標點擊。
變化:
self.entry.focus_set()
到:
self.master.after(200, lambda: self.entry.focus())
來設置焦點返回到輸入字段另一種方法是,以bind()
按鈕釋放事件的焦點命令。
您可以強制重心這樣還有:
self.dropdown.bind("<ButtonRelease-1>", lambda x: self.entry.focus())
下面的代碼應爲您的主要問題的工作:
from tkinter import *
class Autocomplete(Frame, object):
def __init__(self, width, height, entries, *args, **kwargs):
super(Autocomplete, self).__init__(*args, **kwargs)
self.my_list = []
self._entries = entries
self.listbox_height = height
self.entry_width = width
self.text = StringVar()
self.entry = Entry(self, textvariable=self.text, width=self.entry_width)
self.frame = Frame(self)
self.listbox = Listbox(self.frame, height=self.listbox_height, width=self.entry_width)
self.dropdown = Listbox(self.frame, height=self.listbox_height, width=self.entry_width, background="#cfeff9")
def build(self):
self.text.trace("w", lambda name, index, mode: self._update_dropdown())
self.entry.focus_set()
self.entry.pack()
self.frame.pack()
self.listbox.grid(column=0, row=0, sticky=N)
self.dropdown.bind("<<ListboxSelect>>", lambda event: self._select_entry())
self.dropdown.grid(column=0, row=0, sticky=N)
self.dropdown.grid_forget()
return self
def _update_dropdown(self):
self.dropdown["height"] = self.listbox_height
self.dropdown.delete(0, END)
text = self.text.get()
print("update: " + text)
if len(text) < 3:
self.dropdown.grid_forget()
return
else:
for entry in self._entries:
if entry not in self.my_list and text.lower() in entry.lower():
self.dropdown.insert(END, entry)
listbox_size = self.dropdown.size()
if not listbox_size:
self.dropdown.insert(END, "No results found for '{}'".format(text))
self.dropdown["height"] = 1
else:
if listbox_size <= self.dropdown["height"]:
self.dropdown["height"] = listbox_size
self.dropdown.grid(column=0, row=0, sticky=N)
def _shorten_dropdown(self, index):
print("shorten: {}".format(str(index)))
self.dropdown.grid_forget()
self.dropdown.delete(index)
if self.dropdown["height"] == 1:
self.dropdown.insert(END, "No more results found for '{}'".format(self.text.get()))
else:
self.dropdown["height"] -= 1
self.dropdown.selection_clear(0, END)
self.dropdown.grid(column=0, row=0, sticky=N)
def _select_entry(self):
index = self.dropdown.curselection()[0]
value = self.dropdown.get(index)
print(value)
if "results found for" in value:
print("return")
return
print("select: {}".format(value))
self._shorten_dropdown(index)
self._add_course(value)
self.master.after(200, lambda: self.entry.focus())
def _add_course(self, value):
self.entry.delete(0,END)
self.entry.insert(END, value)
self.my_list.append(value)
listt = ["a","aa","aaa","ab","bba","aba","abbnb","cd","c","abc","abcd"]
root = Tk()
autocomplete_frame = Autocomplete(60, 10, listt).build()
autocomplete_frame.pack()
mainloop()
你的代碼是不是測試。我們需要能夠複製粘貼您的代碼並查看您的問題。請提供[最小,完整和可驗證示例](https://stackoverflow.com/help/mcve),以便我們測試您的代碼。 –
@ Mike-SMT我添加了一個鏈接到完整的代碼。 –
到「可測試版本」的鏈接仍然不可測試。你如何創建'Autocomplete()'的對象實例。沒有調用該類的代碼。你不需要提供你所有的代碼。只是一個MCVE。這隻需要包括有問題的方法以及如何創建tkinter實例。您的代碼中沒有'Tk()'或'mainloop()',並且tkinter需要運行。我們需要能夠複製粘貼您的示例,而不必猜測您的課程實施情況。 –