Lut*_*her 1 python autocomplete tkinter
我对Mitja Martini 的 Tkinter 自动完成条目有一些疑问。
我删除了不必要的代码并留下了原作者的评论。如果您输入的速度足够慢,以便在每个字符后突出显示,那么自动完成功能就可以正常工作,但是必须缓慢输入就无法达到自动完成功能的目的,因为节省的时间很少。用户将不得不观看闪烁的突出显示,或者如果他不想观看闪烁,则只需非常慢地键入。
为什么我不能快速打字而不突出显示所选内容并且光标重新定位到填充单词的末尾?结果是快速打字会将字符附加到完整单词的末尾。
如何解决这个问题?
“新的命中列表”是什么意思(有条件注释掉)。我想看一个简单的例子来说明它是如何工作的和/或为什么我不能直接删除这个条件。
“已知命中列表”是什么意思(已注释掉的部分)。这段代码中未知的命中列表的示例是什么,以便我可以看到正在工作的注释行?
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)
Run Code Online (Sandbox Code Playgroud)
自动完成代码的问题在于,它依赖于替换突出显示的文本,因此用户必须等待文本突出显示,然后才能键入下一个字符。发布我的问题后,我从头开始编写了自己的自动完成功能,它使用了一种不同的技术,允许用户在填写单词后继续输入。这并不能回答上述问题,但它解决了我眼前的问题,除非这段代码有一个我还没发现的故障。此部分答案的目的是显示自动填充,该自动填充不会阻止用户在填写单词后进行输入。
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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5757 次 |
| 最近记录: |