Python 在Tkinter中设置自动完成输入小部件的默认文本

Python 在Tkinter中设置自动完成输入小部件的默认文本,python,python-3.x,tkinter,tkinter-entry,Python,Python 3.x,Tkinter,Tkinter Entry,我正在使用tkinter构建一个GUI,它有几个简单的字段。我使用Entry小部件的textvariable参数找到了它们的默认值(我将这些值从.pickle文件加载到字典),但我构建了其中一个字段,以便在用户键入值时使用自动补全。这是一个单独的类,我使用了我找到的代码 在启动应用程序时,我尝试了很多方法来加载这个小部件中的值,比如返回值和使用set()方法,但都没有成功。我要么出错,要么什么都没发生。我在小部件中输入的值会成功保存到pickle文件中 我还在学习用python进行面向对象编程,

我正在使用tkinter构建一个GUI,它有几个简单的字段。我使用Entry小部件的textvariable参数找到了它们的默认值(我将这些值从.pickle文件加载到字典),但我构建了其中一个字段,以便在用户键入值时使用自动补全。这是一个单独的类,我使用了我找到的代码

在启动应用程序时,我尝试了很多方法来加载这个小部件中的值,比如返回值和使用set()方法,但都没有成功。我要么出错,要么什么都没发生。我在小部件中输入的值会成功保存到pickle文件中

我还在学习用python进行面向对象编程,所以请对我放松点。那么我如何修改下面的代码来显示默认值呢

from Tkinter import *
import re

lista = ['a', 'actions', 'additional', 'also', 'an', 'and', 'angle', 'are', 'as', 'be', 'bind','bracket', 'brackets', 'button', 'can', 'cases', 'configure', 'course', 'detail', 'enter', 'event', 'events', 'example', 'field', 'fields', 'for', 'give', 'important', 'in', 'information', 'is', 'it', 'just', 'key', 'keyboard', 'kind', 'leave', 'left', 'like', 'manager', 'many', 'match', 'modifier', 'most', 'of', 'or', 'others', 'out', 'part', 'simplify', 'space', 'specifier', 'specifies', 'string;', 'that', 'the', 'there', 'to', 'type', 'unless', 'use', 'used', 'user', 'various', 'ways', 'we', 'window', 'wish', 'you']


class AutocompleteEntry(Entry):
    def __init__(self, lista, *args, **kwargs):

        Entry.__init__(self, *args, **kwargs)
        self.lista = lista        
        self.var = self["textvariable"]
        if self.var == '':
            self.var = self["textvariable"] = StringVar()

        self.var.trace('w', self.changed)
        self.bind("<Right>", self.selection)
        self.bind("<Up>", self.up)
        self.bind("<Down>", self.down)

        self.lb_up = False

    def changed(self, name, index, mode):  

        if self.var.get() == '':
            self.lb.destroy()
            self.lb_up = False
        else:
            words = self.comparison()
            if words:            
                if not self.lb_up:
                    self.lb = Listbox()
                    self.lb.bind("<Double-Button-1>", self.selection)
                    self.lb.bind("<Right>", self.selection)
                    self.lb.place(x=self.winfo_x(), y=self.winfo_y()+self.winfo_height())
                    self.lb_up = True

                self.lb.delete(0, END)
                for w in words:
                    self.lb.insert(END,w)
            else:
                if self.lb_up:
                    self.lb.destroy()
                    self.lb_up = False

    def selection(self, event):

        if self.lb_up:
            self.var.set(self.lb.get(ACTIVE))
            self.lb.destroy()
            self.lb_up = False
            self.icursor(END)

    def up(self, event):

        if self.lb_up:
            if self.lb.curselection() == ():
                index = '0'
            else:
                index = self.lb.curselection()[0]
            if index != '0':                
                self.lb.selection_clear(first=index)
                index = str(int(index)-1)                
                self.lb.selection_set(first=index)
                self.lb.activate(index) 

    def down(self, event):

        if self.lb_up:
            if self.lb.curselection() == ():
                index = '0'
            else:
                index = self.lb.curselection()[0]
            if index != END:                        
                self.lb.selection_clear(first=index)
                index = str(int(index)+1)        
                self.lb.selection_set(first=index)
                self.lb.activate(index) 

    def comparison(self):
        pattern = re.compile('.*' + self.var.get() + '.*')
        return [w for w in self.lista if re.match(pattern, w)]

if __name__ == '__main__':
root = Tk()

entry = AutocompleteEntry(lista, root)
entry.grid(row=0, column=0)
Button(text='nothing').grid(row=1, column=0)
Button(text='nothing').grid(row=2, column=0)
Button(text='nothing').grid(row=3, column=0)

root.mainloop()
从Tkinter导入*
进口稀土
lista=['a'、'actions'、'additional'、'Allow'、'an'、'an'、'Ang'、'are'、'as'、'be'、'bind'、'bracket'、'button'、'can'、'cases'、'configure'、'course'、'detail'、'enter'、'events'、'events'、'example'、'fields'、'fields'、'for'、'give'、'Essential管理器、多个、匹配、修饰符、大多数、of、or、others、out、part、simplify、space、说明符、specifier、string、that、the、there、to、type、除非、use、used、user、variable、ways、we、window、wish、you']
类自动完成入口(条目):
定义初始值(self、lista、*args、**kwargs):
条目.\uuuuu初始化(self,*args,**kwargs)
self.lista=lista
self.var=self[“textvariable”]
如果self.var='':
self.var=self[“textvariable”]=StringVar()
self.var.trace('w',self.changed)
self.bind(“,self.selection)
self.bind(“,self.up)
self.bind(“,self.down)
self.lb_up=False
def已更改(自身、名称、索引、模式):
如果self.var.get()='':
self.lb.destroy()
self.lb_up=False
其他:
words=self.comparison()
如果用词:
如果不是self.lb_up:
self.lb=Listbox()
self.lb.bind(“,self.selection)
self.lb.bind(“,self.selection)
self.lb.place(x=self.winfo_x(),y=self.winfo_y()+self.winfo_height())
self.lb_up=True
self.lb.delete(0,结束)
对于w,大写:
自磅插入件(端部,w)
其他:
如果self.lb_向上:
self.lb.destroy()
self.lb_up=False
def选择(自身、事件):
如果self.lb_向上:
自变量集(自磅获取(活动))
self.lb.destroy()
self.lb_up=False
自我毁灭(完)
def up(自我,事件):
如果self.lb_向上:
如果self.lb.curselection()==():
索引='0'
其他:
index=self.lb.curselection()[0]
如果索引!=“0”:
自磅选择清除(第一个=索引)
索引=str(整数(索引)-1)
self.lb.selection_set(第一个=索引)
自我激活(索引)
def停机(自身、事件):
如果self.lb_向上:
如果self.lb.curselection()==():
索引='0'
其他:
index=self.lb.curselection()[0]
如果索引!=结束:
自磅选择清除(第一个=索引)
索引=str(整数(索引)+1)
self.lb.selection_set(第一个=索引)
自我激活(索引)
def比较(自我):
pattern=re.compile('.'+self.var.get()+'.'.'')
返回[w代表self.lista中的w,如果重新匹配(模式,w)]
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
root=Tk()
entry=autocompletetentry(lista,root)
entry.grid(行=0,列=0)
按钮(text='nothing').grid(行=1,列=0)
按钮(text='nothing').grid(行=2,列=0)
按钮(text='nothing').grid(行=3,列=0)
root.mainloop()

好的,在分析了这段代码几个小时后,我找到了如何使用
insert()将值设置为默认值
方法。执行此操作后,我遇到的第一个问题是,应用程序启动时,列表框默认也处于活动状态。通过向
changed
函数添加另一个if条件,在清除该值之前,它不会打开列表框。当我添加条件语句时,行
self.lb.destroy()
清除字段时抛出错误:

AttributeError:“AutoCompleteTentry”对象没有属性“lb”

我不知道为什么会抛出此错误,因为它在我添加条件之前就已生效。但是,
lb
未在类或函数中的任何其他位置定义。删除该行修复了此错误,并且所有操作似乎都按预期工作。以下是我所做的更改。如果其他人有更好的解决方案,请告诉我

class AutocompleteEntry(Entry):
    # add settings argument which is True or False    
    def __init__(self, lista, settings, *args, **kwargs):

        Entry.__init__(self, *args, **kwargs)
        self.lista = lista
        # define the self.settings object
        self.settings = settings
        self.var = self["textvariable"]
        if self.var == '':
            self.var = self["textvariable"] = StringVar()
        self.var.trace('w', self.changed)
        self.bind("<Return>", self.selection)
        self.bind("<Up>", self.up)
        self.bind("<Down>", self.down)

        self.lb_up = False

    def changed(self, name, index, mode):

        if self.var.get() == '':
            # self.lb.destroy() - removed this line
            self.lb_up = False
            # change this variable to False once the field is cleared
            self.settings = False 
        # add if condition - field is not empty and settings is True
        elif self.var.get() != '' and self.settings == True:
            self.lb_up = False
        else:
            words = self.comparison()
            if words:
                if not self.lb_up:
                    self.lb = Listbox()
                    self.lb.bind("<Double-Button-1>", self.selection)
                    self.lb.bind("<Return>", self.selection)
                    self.lb.place(x=self.winfo_x(), y=self.winfo_y()+self.winfo_height())
                    self.lb_up = True

                self.lb.delete(0, END)
                for w in words:
                    self.lb.insert(END,w)
            else:
                if self.lb_up:
                    self.lb.destroy()
                    self.lb_up = False

@BryanOakley抱歉-现在修好了..我想
if __name__ == '__main__':
    root = Tk()
    # define settings variable and add to AutoCompleteEntry arguments
    settings = True
    entry = AutocompleteEntry(lista, settings, root)
    entry.insert(END, "this is the default value")
    entry.grid(row=0, column=0)
    Button(text='nothing').grid(row=1, column=0)
    Button(text='nothing').grid(row=2, column=0)
    Button(text='nothing').grid(row=3, column=0)

    root.mainloop()