阐明 Tkinter 自动完成条目的功能
Clarify functionality of Tkinter Autocomplete Entry
我对此有一些疑问Tkinter autocomplete entry by Mitja Martini。
我已经删除了不必要的代码并留下了原作者的评论。如果您键入的速度足够慢,以便在每个字符后突出显示,则自动完成会正常工作,但是必须缓慢键入会破坏自动完成的目的,因为节省的时间很少。用户将不得不观看闪烁的亮点,或者如果他不想观看闪光灯,则只能非常缓慢地键入。
为什么我不能快速打字,而不会取消突出显示所选内容,并且光标会重新定位到所填词的末尾;结果是快速打字将字符追加到完整单词的末尾。
如何解决这个问题?
"a new hit list"是什么意思(有条件的注释掉)。我想看一个简单的例子来说明它是如何工作的 and/or 为什么我不能只删除这个条件。
"known hit list" 是什么意思(注释掉的部分)。此代码中未知命中列表的示例是什么,以便我可以看到注释行?
import tkinter as tk
class AutocompleteEntry(tk.Entry):
def set_completion_list(self, completion_list):
self._completion_list = completion_list
self._hits = []
self._hit_index = 0
self.position = 0
self.bind('<KeyRelease>', self.handle_keyrelease)
def autocomplete(self):
# set position to end so selection starts where textentry ended
self.position = len(self.get())
# collect hits
_hits = []
for element in self._completion_list:
if element.lower().startswith(self.get().lower()):
_hits.append(element)
# if we have a new hit list, keep this in mind
# if _hits != self._hits:
self._hit_index = 0
self._hits =_hits
# # only allow cycling if we are in a known hit list
# if _hits == self._hits and self._hits:
# self._hit_index = (self._hit_index) % len(self._hits)
# perform the auto completion
if self._hits:
self.delete(0,tk.END)
self.insert(0,self._hits[self._hit_index])
self.select_range(self.position,tk.END)
def handle_keyrelease(self, event):
if len(event.keysym) == 1:
self.autocomplete()
def test(test_list):
root = tk.Tk(className=' AutocompleteEntry demo')
root.geometry('+500+300')
entry = AutocompleteEntry(
root,
fg='white', bg='black',
insertbackground='white',
font=('arial', 30))
entry.set_completion_list(test_list)
entry.grid()
entry.focus_set()
root.mainloop()
if __name__ == '__main__':
test_list = (
'Geronimo', 'Tecumseh', 'onomatopoeia',
'onerous', 'technicality', 'geriatric' )
test(test_list)
自动完成代码的问题在于它依赖于替换突出显示的文本,因此用户必须等待文本突出显示才能键入下一个字符。发布我的问题后,我从头开始编写了自己的自动完成功能,它使用了一种不同的技术,允许用户在填写完单词后继续输入。这并没有回答上面提到的问题,但它解决了我眼前的问题,除非这段代码有一个我还没有发现的故障。这个部分答案的目的是显示一个自动填充,它不会阻止用户在填写单词后进行输入。
import tkinter as tk
chiefs = [
'Sitting Bull', 'Geronimo', 'Tecumseh', 'Pontiac',
'Red Cloud', 'Crazy Horse', 'Cochise', 'Red Jacket',
'Red Czar', 'Red Czechoslovakian']
def match_string():
hits = []
got = auto.get()
for item in chiefs:
if item.startswith(got):
hits.append(item)
return hits
def get_typed(event):
if len(event.keysym) == 1:
hits = match_string()
show_hit(hits)
def show_hit(lst):
if len(lst) == 1:
auto.set(lst[0])
detect_pressed.filled = True
def detect_pressed(event):
key = event.keysym
if len(key) == 1 and detect_pressed.filled is True:
pos = autofill.index(tk.INSERT)
autofill.delete(pos, tk.END)
detect_pressed.filled = False
root = tk.Tk()
auto = tk.StringVar()
autofill = tk.Entry(
root,
font=('tacoma', 30),
bg='black',
insertbackground='white',
fg='white',
textvariable=auto)
autofill.grid()
autofill.focus_set()
autofill.bind('<KeyRelease>', get_typed)
autofill.bind('<Key>', detect_pressed)
root.mainloop()
我对此有一些疑问Tkinter autocomplete entry by Mitja Martini。
我已经删除了不必要的代码并留下了原作者的评论。如果您键入的速度足够慢,以便在每个字符后突出显示,则自动完成会正常工作,但是必须缓慢键入会破坏自动完成的目的,因为节省的时间很少。用户将不得不观看闪烁的亮点,或者如果他不想观看闪光灯,则只能非常缓慢地键入。
为什么我不能快速打字,而不会取消突出显示所选内容,并且光标会重新定位到所填词的末尾;结果是快速打字将字符追加到完整单词的末尾。
如何解决这个问题?
"a new hit list"是什么意思(有条件的注释掉)。我想看一个简单的例子来说明它是如何工作的 and/or 为什么我不能只删除这个条件。
"known hit list" 是什么意思(注释掉的部分)。此代码中未知命中列表的示例是什么,以便我可以看到注释行?
import tkinter as tk
class AutocompleteEntry(tk.Entry):
def set_completion_list(self, completion_list):
self._completion_list = completion_list
self._hits = []
self._hit_index = 0
self.position = 0
self.bind('<KeyRelease>', self.handle_keyrelease)
def autocomplete(self):
# set position to end so selection starts where textentry ended
self.position = len(self.get())
# collect hits
_hits = []
for element in self._completion_list:
if element.lower().startswith(self.get().lower()):
_hits.append(element)
# if we have a new hit list, keep this in mind
# if _hits != self._hits:
self._hit_index = 0
self._hits =_hits
# # only allow cycling if we are in a known hit list
# if _hits == self._hits and self._hits:
# self._hit_index = (self._hit_index) % len(self._hits)
# perform the auto completion
if self._hits:
self.delete(0,tk.END)
self.insert(0,self._hits[self._hit_index])
self.select_range(self.position,tk.END)
def handle_keyrelease(self, event):
if len(event.keysym) == 1:
self.autocomplete()
def test(test_list):
root = tk.Tk(className=' AutocompleteEntry demo')
root.geometry('+500+300')
entry = AutocompleteEntry(
root,
fg='white', bg='black',
insertbackground='white',
font=('arial', 30))
entry.set_completion_list(test_list)
entry.grid()
entry.focus_set()
root.mainloop()
if __name__ == '__main__':
test_list = (
'Geronimo', 'Tecumseh', 'onomatopoeia',
'onerous', 'technicality', 'geriatric' )
test(test_list)
自动完成代码的问题在于它依赖于替换突出显示的文本,因此用户必须等待文本突出显示才能键入下一个字符。发布我的问题后,我从头开始编写了自己的自动完成功能,它使用了一种不同的技术,允许用户在填写完单词后继续输入。这并没有回答上面提到的问题,但它解决了我眼前的问题,除非这段代码有一个我还没有发现的故障。这个部分答案的目的是显示一个自动填充,它不会阻止用户在填写单词后进行输入。
import tkinter as tk
chiefs = [
'Sitting Bull', 'Geronimo', 'Tecumseh', 'Pontiac',
'Red Cloud', 'Crazy Horse', 'Cochise', 'Red Jacket',
'Red Czar', 'Red Czechoslovakian']
def match_string():
hits = []
got = auto.get()
for item in chiefs:
if item.startswith(got):
hits.append(item)
return hits
def get_typed(event):
if len(event.keysym) == 1:
hits = match_string()
show_hit(hits)
def show_hit(lst):
if len(lst) == 1:
auto.set(lst[0])
detect_pressed.filled = True
def detect_pressed(event):
key = event.keysym
if len(key) == 1 and detect_pressed.filled is True:
pos = autofill.index(tk.INSERT)
autofill.delete(pos, tk.END)
detect_pressed.filled = False
root = tk.Tk()
auto = tk.StringVar()
autofill = tk.Entry(
root,
font=('tacoma', 30),
bg='black',
insertbackground='white',
fg='white',
textvariable=auto)
autofill.grid()
autofill.focus_set()
autofill.bind('<KeyRelease>', get_typed)
autofill.bind('<Key>', detect_pressed)
root.mainloop()