Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 一次按下多个键时自动完成失败_Python_Tkinter_Autocomplete - Fatal编程技术网

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)
    
  • 用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)
    
  • 用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)
    
  • 用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)
    
  • 选择条目中的所有文本

      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()
    
  • 用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)
    
  • 把所有的东西放在一起
    导入字符串
    从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()