问题
I'm trying to create a GUI application using Tkinter
. This interface is made of the following widgets: a button, an entry and a text.
The image below shows it.
The idea behind this app is: the user enters a word on the entry and on hit the Meaning button it's meaning is showed in the text widget.
My code is splitted in two classes: one for GUI and another for the app itself.
GUI (removed the imaged showed before to reduce coding):
class Gui:
def __init__(self, master=None):
if master is None:
return
else:
self.word = StringVar()
self.word_meaning = None
self.app_frame = Frame(master)
self.app_frame.grid()
self.create_app_frame()
self.entry_widget = Entry(self.app_frame, textvariable=self.word)
self.button_widget = Button(self.app_frame, text='Meaning', command=self.__handler_entry)
self.text_widget = Text(self.app_frame, height=10, width=30)
self.crete_app_frame()
def crete_app_frame(self):
self.entry_widget.grid(row=0, column=0)
self.button_widget.grid(row=0, column=1)
self.text_widget.grid(row=1, column=0, columnspan=2)
def get_word(self):
return self.word.get()
def set_word_meaning(self, meaning):
self.word_meaning = meaning
def __handler_entry(self):
self.text_widget.delete(0., END)
self.text_widget.insert(END, self.word_meaning)
Application:
class InteractiveDictionary:
def __init__(self, filename):
with open(filename, 'r') as file:
self.data = json.load(file)
def get_meaning(self, term):
print('-------------------')
print(f"world is:{term}")
print('-------------------')
term = str(term)
term = term.lower()
if term in self.data:
return self.data[term]
else:
return "The world you\'re looking for doesn\'t exist."
Main:
if __name__ == '__main__':
window = Tk()
window.title('Interactive Dictionary')
dictionary = InteractiveDictionary('words.json')
app = Gui(master=window)
word = app.get_word()
word_meaning = dictionary.get_meaning(word)
if type(word_meaning) == list:
for i in word_meaning:
app.set_word_meaning(i)
else:
app.set_word_meaning(word_meaning)
window.mainloop()
The application works fine when results are shown on console. However, when I try to show on the GUI, the word captured by get_word()
method is not correctly passed to dictionaries get_meaning()
method. An empty is passed.
My suspect that it is related to the way I call Tkinter on main.
I would like to keep Gui and the app isolated. So, remove code in the main to __handler_entry()
is not an option. Someone knows how can I fix it and made my app run properly?
回答1:
It seems you don't know how GUIs works - all starts with mainloop()
, it displays window, gets mouse/keyboard events from system, sends events to widgets, (re)draws widgets.
Everything before mainloop()
is executed before you see window - so word = app.get_word()
is executed before you see window. You have to use it in __handler_entry
which is executed when you press button.
More precisly in __handler_event` you will have to use all of this
def __handler_entry(self):
word = self.get_word()
word_meaning = dictionary.get_meaning(word)
if isinstance(word_meaning, list):
for i in word_meaning:
self.set_word_meaning(i)
else:
self.set_word_meaning(word_meaning)
self.text_widget.delete(0., END)
self.text_widget.insert(END, self.word_meaning)
来源:https://stackoverflow.com/questions/55773536/tkinter-entry-always-returning-empty-string