Python 一次按下多个键时自动完成失败
我正在尝试制作一个自动完成功能,用于选择字体,其中必须选择除用户插入的文本之外的其余文本 我已成功编写了一个工作代码,但同时按下两个键时失败。当我同时按下两个键时,第一个匹配的值被插入到条目小部件中,而不选择其余的字母 如何选择要自动完成的其余字母 即使同时按下两个键,也会显示文本 代码Python 一次按下多个键时自动完成失败,python,tkinter,autocomplete,Python,Tkinter,Autocomplete,我正在尝试制作一个自动完成功能,用于选择字体,其中必须选择除用户插入的文本之外的其余文本 我已成功编写了一个工作代码,但同时按下两个键时失败。当我同时按下两个键时,第一个匹配的值被插入到条目小部件中,而不选择其余的字母 如何选择要自动完成的其余字母 即使同时按下两个键,也会显示文本 代码 import string import tkinter as tk from tkinter import font class AutoComplete: def __init__(self):
import string
import tkinter as tk
from tkinter import font
class AutoComplete:
def __init__(self):
self.keys = []
self.function_keys = ['Ctrl_L', 'Ctrl_R', 'Shift_L', 'Shift_R', 'Alt_L', 'Alt_R']
self.root = tk.Tk()
self.test_list = self.non_duplicate_fonts()
self.entry_var = tk.StringVar()
self.entry = tk.Entry(self.root, textvariable=self.entry_var)
self.entry.pack()
self.entry.focus_set()
self.lis_var = tk.Variable(self.root, value=self.test_list)
self.listbox = tk.Listbox(self.root, listvariable=self.lis_var)
self.listbox.pack()
self.entry.bind('<KeyPress>', self.key_pressed)
self.entry.bind('<KeyRelease>', self.on_keyrelease)
self.root.mainloop()
def is_function_key_available(self):
for key in self.keys:
if key in self.function_keys:
return True
return False
def non_duplicate_fonts(self):
'''Filter fonts starting with same name'''
fonts = list(font.families())
fonts.sort()
fonts = fonts[26:]
prev_family = ' '
_fonts = []
for family in fonts:
if not family.startswith(prev_family):
_fonts.append(family)
prev_family = family
return _fonts
def on_keyrelease(self, event):
if self.is_function_key_available():
self.keys = []
return
elif event.keysym in string.printable:
value = self.entry_var.get().strip().lower()
lowered_list = [k.lower() for k in self.test_list]
matched_value = [f for f in lowered_list if f.startswith(value)]
if matched_value:
index = lowered_list.index(matched_value[0])
self.entry_var.set(self.test_list[index])
self.entry.selection_range(len(value), 'end')
self.keys = []
def key_pressed(self, event):
key = event.keysym
if key not in self.keys:
self.keys.append(key)
if __name__ == '__main__':
AutoComplete()
导入字符串
将tkinter作为tk导入
从tkinter导入字体
类自动完成:
定义初始化(自):
self.keys=[]
self.function\u keys=['Ctrl\u L','Ctrl\u R','Shift\u L','Shift\u R','Alt\u L','Alt\u R']
self.root=tk.tk()
self.test\u list=self.non\u replicate\u字体()
self.entry_var=tk.StringVar()
self.entry=tk.entry(self.root,textvariable=self.entry\u var)
self.entry.pack()
self.entry.focus_set()
self.lis\u var=tk.Variable(self.root,value=self.test\u list)
self.listbox=tk.listbox(self.root,listvariable=self.lis\u var)
self.listbox.pack()
self.entry.bind(“”,按下self.key)
self.entry.bind(“”,self.on_键释放)
self.root.mainloop()
def功能键可用(自身):
对于键入self.keys:
如果输入self.function\u键:
返回真值
返回错误
def非重复字体(自身):
''筛选以相同名称开头的字体''
字体=列表(font.families())
字体排序()
字体=字体[26:]
上一个家庭=“”
_字体=[]
对于字体中的族:
如果不是族,则开始使用(上一个族):
_字体.附加(族)
prev_族=族
返回字体
钥匙释放时的def(自身,事件):
如果self.u功能键可用():
self.keys=[]
返回
string.printable中的elif event.keysym:
value=self.entry\u var.get().strip().lower()
lowered_list=[k.lower()表示self.test_list中的k]
匹配的_值=[f表示降低的_列表中的f,如果f.startswith(值)]
如果匹配_值:
索引=降低的\u列表。索引(匹配的\u值[0])
self.entry\u var.set(self.test\u列表[索引])
self.entry.selection_范围(len(value),'end')
self.keys=[]
按def键(自身,事件):
key=event.keysym
如果键不在self.keys中:
self.keys.append(key)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
自动完成()
导入
import string
from tkinter import *
from tkinter import font
class AutoComplete:
def __init__(self):
self.root = Tk()
self.root.title('AutoComplete')
self.ent_var = StringVar()
self.entry = Entry(self.root, textvariable=self.ent_var, width=50)
self.entry.pack()
self.list_var = Variable(self.entry)
self.listbox = Listbox(self.root, listvariable=self.list_var, width=50)
self.listbox.pack()
self.all_fonts = list(font.families())
self.all_fonts.sort()
self.all_fonts = self.all_fonts[26:]
self.non_duplicates_fonts()
self.lower_case = [f.lower() for f in self.all_fonts]
self.list_var.set(self.all_fonts)
self.entry.focus()
self.root.resizable(0, 0)
self.root.mainloop()
def non_duplicates_fonts(self):
'''Filter fonts starting with same name'''
prev_family = ' '
font_families = []
for family in self.all_fonts:
if not family.startswith(prev_family):
font_families.append(family)
prev_family = family
self.all_fonts = font_families
def default(self):
'''Set default values in entry widget and listbox'''
self.listbox.selection_set(3)
self.ent_var.set('Arial')
self.entry.config(insertofftime=1000000, insertontime=0)
self.set_selection()
设置小部件
import string
from tkinter import *
from tkinter import font
class AutoComplete:
def __init__(self):
self.root = Tk()
self.root.title('AutoComplete')
self.ent_var = StringVar()
self.entry = Entry(self.root, textvariable=self.ent_var, width=50)
self.entry.pack()
self.list_var = Variable(self.entry)
self.listbox = Listbox(self.root, listvariable=self.list_var, width=50)
self.listbox.pack()
self.all_fonts = list(font.families())
self.all_fonts.sort()
self.all_fonts = self.all_fonts[26:]
self.non_duplicates_fonts()
self.lower_case = [f.lower() for f in self.all_fonts]
self.list_var.set(self.all_fonts)
self.entry.focus()
self.root.resizable(0, 0)
self.root.mainloop()
def non_duplicates_fonts(self):
'''Filter fonts starting with same name'''
prev_family = ' '
font_families = []
for family in self.all_fonts:
if not family.startswith(prev_family):
font_families.append(family)
prev_family = family
self.all_fonts = font_families
def default(self):
'''Set default values in entry widget and listbox'''
self.listbox.selection_set(3)
self.ent_var.set('Arial')
self.entry.config(insertofftime=1000000, insertontime=0)
self.set_selection()
设置默认值
import string
from tkinter import *
from tkinter import font
class AutoComplete:
def __init__(self):
self.root = Tk()
self.root.title('AutoComplete')
self.ent_var = StringVar()
self.entry = Entry(self.root, textvariable=self.ent_var, width=50)
self.entry.pack()
self.list_var = Variable(self.entry)
self.listbox = Listbox(self.root, listvariable=self.list_var, width=50)
self.listbox.pack()
self.all_fonts = list(font.families())
self.all_fonts.sort()
self.all_fonts = self.all_fonts[26:]
self.non_duplicates_fonts()
self.lower_case = [f.lower() for f in self.all_fonts]
self.list_var.set(self.all_fonts)
self.entry.focus()
self.root.resizable(0, 0)
self.root.mainloop()
def non_duplicates_fonts(self):
'''Filter fonts starting with same name'''
prev_family = ' '
font_families = []
for family in self.all_fonts:
if not family.startswith(prev_family):
font_families.append(family)
prev_family = family
self.all_fonts = font_families
def default(self):
'''Set default values in entry widget and listbox'''
self.listbox.selection_set(3)
self.ent_var.set('Arial')
self.entry.config(insertofftime=1000000, insertontime=0)
self.set_selection()
要在tkinter中自动完成功能,需要绑定
您的文本小部件使用bindtags来检测是否有任何键
都压下来了
按下按键后,您需要检查:
- 将空格转换为“”
- 仅当每个按下的键可打印时,才将其存储到变量中
- 如果条目小部件中存在选择,则移除所选文本,插入与条目小部件中存在的文本一起按下的键,并将光标向前移动一步。还通过增加1来存储起始索引,以便我们可以使用它来选择剩余的文本
如果没有选择,则将起始索引增加1,然后重复剩余的步骤
def key_pressed(self, event=None): key = event.keysym if key == 'space': key = ' ' if key in string.printable: if self.entry.selection_present(): self.sel = self.entry.index('sel.first') + 1 self.entry.delete('sel.first', 'sel.last') else: self.sel = self.entry.index('insert') + 1 value = self.ent_var.get() + key self.ent_var.set(value) self.ent_index += 1 self.entry.icursor(self.ent_index) self.auto_complete() # Explained below return 'break'
- 用bindtag绑定条目小部件
self.entry.bind('<KeyPress>', self.key_pressed)
self.entry.bind('<BackSpace>', self.backspace)
self.entry.bind('<Tab>', self.tab_completion)
self.entry.bind('<Up>', self.up_direction)
self.entry.bind('<Down>', self.down_direction)
self.listbox.bind('<<ListboxSelect>>', self.button_click)
self.entry.bind('<KeyPress>', self.key_pressed)
self.entry.bind('<BackSpace>', self.backspace)
self.entry.bind('<Tab>', self.tab_completion)
self.entry.bind('<Up>', self.up_direction)
self.entry.bind('<Down>', self.down_direction)
self.listbox.bind('<<ListboxSelect>>', self.button_click)
self.entry.bind('<KeyPress>', self.key_pressed)
self.entry.bind('<BackSpace>', self.backspace)
self.entry.bind('<Tab>', self.tab_completion)
self.entry.bind('<Up>', self.up_direction)
self.entry.bind('<Down>', self.down_direction)
self.listbox.bind('<<ListboxSelect>>', self.button_click)
self.entry.bind('<KeyPress>', self.key_pressed)
self.entry.bind('<BackSpace>', self.backspace)
self.entry.bind('<Tab>', self.tab_completion)
self.entry.bind('<Up>', self.up_direction)
self.entry.bind('<Down>', self.down_direction)
self.listbox.bind('<<ListboxSelect>>', self.button_click)
def up_direction(self, event=None):
'''Move selection in upwards direction in listbox'''
index = self.listbox.curselection()[0]
if index > 0:
index -= 1
self.listbox.selection_clear(0, 'end')
self.listbox.selection_set(index)
self.listbox.see(index)
self.ent_var.set(self.all_fonts[index])
self.entry.selection_range(0, 'end')
return 'break'
def down_direction(self, event=None):
'''Move selection in downwards direction in listbox'''
index = self.listbox.curselection()[0]
if index < len(self.all_fonts) - 1:
index += 1
self.listbox.selection_clear(0, 'end')
self.listbox.selection_set(index)
self.listbox.see(index)
self.ent_var.set(self.all_fonts[index])
self.entry.selection_range(0, 'end')
return 'break'
def button_click(self, event=None):
'''When selection is made by clicking'''
index = self.listbox.curselection()[0]
self.ent_var.set(self.all_fonts[index])
self.root.after(10, self.set_selection)
def set_selection(self):
'''Select all text in entry widget'''
self.entry.select_range(0, 'end')
self.entry.focus()
self.entry.bind('<KeyPress>', self.key_pressed)
self.entry.bind('<BackSpace>', self.backspace)
self.entry.bind('<Tab>', self.tab_completion)
self.entry.bind('<Up>', self.up_direction)
self.entry.bind('<Down>', self.down_direction)
self.listbox.bind('<<ListboxSelect>>', self.button_click)
导入字符串
从tkinter进口*
从tkinter导入字体
类自动完成:
定义初始化(自):
self.ent_索引=0
self.root=Tk()
self.root.title('AutoComplete')
self.ent_var=StringVar()
self.entry=entry(self.root,textvariable=self.ent\u var,width=50)
self.entry.pack()
self.list_var=变量(self.entry)
self.listbox=listbox(self.root,listvariable=self.list\u var,exportselection=False,activestyle='none',selectmode=SINGLE,width=50)
self.listbox.pack()
self.all_font=列表(font.families())
self.all_font.sort()
self.all_字体=self.all_字体[26:]
self.non_duplicates_字体()
self.lower\u case=[f.lower()表示self.all\u字体中的f]
self.list\u var.set(self.all\u字体)
self.entry.focus()
self.entry.bind(“”,self.up_方向)
self.entry.bind(“”,self.tab_完成)
self.entry.bind(“”,self.backspace)
self.entry.bind(“”,self.down_方向)
self.entry.bind(“”,按下self.key)
self.listbox.bind(“”,self.button\u单击)
self.default()
self.root.reshable(0,0)
self.root.mainloop()
def非重复字体(自身):
''筛选以相同名称开头的字体''
上一个家庭=“”
font_系列=[]
对于使用self.all_字体的家庭:
如果不是族,则开始使用(上一个族):
font\u族。附加(族)
prev_族=族
self.all\u字体=字体\u系列
def默认值(自我):
''在条目小部件和列表框中设置默认值''
self.listbox.selection\u集(3)
self.ent_变量集('Arial')
self.entry.config(insertofftime=1000000,insertontime=0)
self.set_selection()