基本上我尝试这样做,以便当您更改Entry
输入字段时,该按钮会将其标签附加到正确的输入。
我使用active_entry
来定位刚关注的输入。由于某种原因,事件绑定没有正确地将其更改为新的输入字段。
更改默认Entry
然后按button_1
后的实际结果:TypeError: getattr(): attribute name must be string
from tkinter import *
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.set_active_entry('entry_1_var') # set initial active entry
self.entry_1_var = StringVar()
self.entry_2_var = StringVar()
self.entry_1 = Entry(self, width=10, font='Helvetica 32', textvariable=self.entry_1_var)
self.entry_2 = Entry(self, width=10, font='Helvetica 32', textvariable=self.entry_2_var)
self.create_widgets()
self.entry_binding()
def set_active_entry(self, name):
self._active_entry = name
print(self._active_entry)
@property
def active_entry(self):
return getattr(self, self._active_entry)
@active_entry.setter
def active_entry(self, value):
setattr(self, self._active_entry, value)
def create_widgets(self):
self.entry_1.pack()
self.entry_2.pack()
label = '1'
button_1 = Button(self, text=label, width=10, height=5, command=lambda x=label: self.num_pad(x))
button_1.pack()
def entry_binding(self):
self.entry_1.bind('<FocusIn>', lambda x='entry_1_var': self.set_active_entry(x))
self.entry_2.bind('<FocusIn>', lambda x='entry_2_var': self.set_active_entry(x))
def num_pad(self, label):
current_text = self.active_entry.get()
self.active_entry.set(current_text+label)
app = App()
app.mainloop()
答案 0 :(得分:1)
问题出在这些方面
self.entry_1.bind('<FocusIn>', lambda x='entry_1_var': self.set_active_entry(x))
self.entry_2.bind('<FocusIn>', lambda x='entry_2_var': self.set_active_entry(x))
当您点击其中一个条目时,您会看到<FocusIn event>
正在打印,相反,您可能会认为它是entry_1_var
或entry_2_var
吗?
当bind
函数自动将事件对象传递给您指定的函数时,会发生什么。在lambda函数中,第一个参数是x
。您确实指定了默认值,但由于bind
函数传递了实际对象,因此x是事件对象。因此,在def set_active_entry(self, name):
中,name
不是您的小部件的名称,而是事件对象。因此,当您致电getattr(self, self._active_entry)
时,self._active_entry
是事件对象,您会收到错误。
对此的修复实际上非常简单,只需在lambda函数中接受一个参数来接受事件对象,并确保实际将带有名称的字符串传递给set_active_entry
函数:
self.entry_1.bind('<FocusIn>', lambda e, x='entry_1_var': self.set_active_entry(x))
self.entry_2.bind('<FocusIn>', lambda e, x='entry_2_var': self.set_active_entry(x))
或
self.entry_1.bind('<FocusIn>', lambda e: self.set_active_entry('entry_1_var'))
self.entry_2.bind('<FocusIn>', lambda e: self.set_active_entry('entry_2_var'))