【发布时间】:2017-09-25 17:53:40
【问题描述】:
我有一个条目、一个列表框(下拉列表)和另一个列表框。每当在条目中键入超过 3 个字符时。查找完成列表并将其插入到下拉列表中,然后显示下拉列表。如果从下拉列表中选择了一个项目。它的值应该被插入到列表框中并从下拉列表中删除,并且该条目应该再次获得焦点。但事实并非如此。
这是我的代码:
from tkinter import *
class Autocomplete(Frame, object):
def __init__(self, *args, **kwargs):
super(Autocomplete, self).__init__(*args, **kwargs)
self.text = StringVar()
self.entry = Entry(self, textvariable=self.text)
self.frame = Frame(self)
self.listbox = Listbox(self.frame)
self.dropdown = Listbox(self.frame)
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 _shorten_dropdown(self, index):
self.dropdown.grid_forget()
self.dropdown.delete(index)
self.dropdown["height"] -= 1
self.dropdown.selection_clear(0, END)
self.dropdown.grid(column=0, row=0, sticky=N)
def _select_entry(self):
index = int(self.dropdown.curselection()[0])
value = self.dropdown.get(index)
self._shorten_dropdown(index)
self.entry.focus_set()
这是最少的代码。 Here 是可测试的版本。下面是构建自动完成实例的代码:
from tkinter import *
from autocomplete import Autocomplete
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()
【问题讨论】:
-
您的代码不可测试。我们需要能够复制粘贴您的代码并查看您的问题。请提供Minimal, Complete, and Verifiable example,以便我们测试您的代码。
-
指向您的“可测试版本”的链接仍然不可测试。您如何创建
Autocomplete()的对象实例。没有调用该类的代码。您无需提供所有代码。只是一个 MCVE。这只需要包括有问题的方法以及您如何创建 tkinter 实例。您的代码中没有Tk()或mainloop(),它是 tkinter 运行所必需的。我们需要能够复制粘贴您的示例,而不必猜测您是如何实现您的课程的。 -
您拥有的第二个链接应该是您原始问题代码的一部分。
-
abc""中的拼写错误listt是您原始代码的一部分吗?这可能会导致问题。 -
没关系。我刚刚注意到您问题中的类型,所以我想我应该指出它以防万一。至于你的代码的其余部分,我在尝试实现你的类时遇到了引用错误。这条线
super(Autocomplete, self).__init__(*args, **kwargs)引起了问题。TypeError: __init__() takes from 1 to 3 positional arguments but 4 were given