Reputation:
I am creating a simple GUI application to manage unknown words when learning a new language. I am trying to handle the window close event. I am getting:
/usr/bin/python3.5 /home/cali/PycharmProjects/Vocabulary/Vocabulary.py
Traceback (most recent call last):
File "/home/cali/PycharmProjects/Vocabulary/Vocabulary.py", line 171, in <module>
main()
File "/home/cali/PycharmProjects/Vocabulary/Vocabulary.py", line 162, in main
Vocabulary(root)
File "/home/cali/PycharmProjects/Vocabulary/vocabulary.py", line 28, in __init__
self.root = root
NameError: name 'root' is not defined
Process finished with exit code 1
Here is what I have done:
#!/usr/bin/env python
# Vocabulary.py
# GUI program to manage unknown words
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class Word:
def __init__(self, wordorphrase, explanation, translation, example):
self.wordorphrase = wordorphrase
self.explanation = explanation
self.example = example
self.translation = translation
class Vocabulary(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master = master
self.master.resizable(width = False, height = False)
self.master.title("Vocabulary")
self.create_widgets()
self.words = []
self.root = root
def create_widgets(self):
self.buttons_frame = Frame(self.master)
self.buttons_frame.grid(row = 10, sticky = W)
self.search_frame = Frame(self.master)
self.search_frame.grid(row = 1, sticky = W, columnspan = 2)
self.comboBox = ttk.Combobox(self.search_frame,
width = 3)
self.comboBox.grid(row = 0, column = 14, sticky = W)
self.btn_Add = Button(self.buttons_frame,
text = 'Add',
command = self.add_item)
self.btn_Add.grid(row = 0, sticky = W)
self.btn_Remove = Button(self.buttons_frame,
text = 'Remove',
command = self.remove_item)
self.btn_Remove.grid(row = 0, column = 1, sticky = W)
self.btn_Edit = Button(self.buttons_frame,
text = 'Edit',
command = self.edit_item)
self.btn_Edit.grid(row = 0, column = 2, sticky = W)
self.btn_Save = Button(self.buttons_frame,
text = 'Save',
command = self.save_item)
self.btn_Save.grid(row = 0, column = 3, sticky = W)
self.btn_Refresh = Button(self.buttons_frame,
text = 'Refresh',
command = self.refresh_all)
self.btn_Refresh.grid(row = 0, column = 4, sticky = W)
self.lblSearch = Label(self.search_frame, text = 'SEARCH: ')
self.lblSearch.grid(row = 0, column = 5, sticky = W)
self.txt_Search = Text(self.search_frame,
height = 1,
width = 70)
self.txt_Search.grid(row = 0, column = 6, columnspan = 3, sticky = W)
self.lblWordsOrPhrases = Label(self.master, text = 'WORDS/PHRASES:')
self.lblWordsOrPhrases.grid(row = 2, column = 0)
self.lblWordOrPhrase = Label(self.master, text = 'Word or phrase:')
self.lblWordOrPhrase.grid(row = 2, column = 1, sticky = W)
self.listBox = Listbox(self.master,
selectmode='multiple',
height = 34,
width = 38)
self.listBox.grid(row = 3, column = 0, rowspan = 7, sticky = W)
self.txt_WordOrPhrase = Text(self.master,
height = 1,
width = 40)
self.txt_WordOrPhrase.grid(row = 3, column = 1, sticky = N)
self.lblExplanation = Label(self.master, text = 'Explanation:')
self.lblExplanation.grid(row = 4, column = 1, sticky = W)
self.txt_Explanation = Text(self.master,
height = 10,
width = 40)
self.txt_Explanation.grid(row = 5, column = 1, sticky = N)
self.lblTranslation = Label(self.master, text = 'Translation:')
self.lblTranslation.grid(row = 6, column = 1, sticky = W)
self.txt_Translation = Text(self.master,
height = 10,
width = 40)
self.txt_Translation.grid(row = 7, column = 1, sticky = N)
self.lblExamples = Label(self.master, text = 'Example(s):')
self.lblExamples.grid(row = 8, column = 1, sticky = W)
self.txt_Example = Text(self.master,
height = 10,
width = 40)
self.txt_Example.grid(row = 9, column = 1, sticky = S)
def get_word(self):
return self.txt_WordOrPhrase.get('1.0', '1.0 lineend')
def get_explanation(self):
return self.txt_Explanation.get('1.0', '1.0 lineend')
def get_translation(self):
return self.txt_Translation.get('1.0', '1.0 lineend')
def get_example(self):
return self.txt_Example.get('1.0', '1.0 lineend')
def add_item(self):
w = Word(self.get_word(), self.get_explanation(), self.get_translation(), self.get_example())
self.words.append(w)
self.listBox.insert(END, w.wordorphrase)
self.clear_all()
def remove_item(self):
self.listBox.delete(ANCHOR)
self.words.remove()
def edit_item(self):
pass
def save_item(self):
pass
def clear_all(self):
self.txt_WordOrPhrase.delete('1.0', END)
self.txt_Explanation.delete('1.0', END)
self.txt_Translation.delete('1.0', END)
self.txt_Example.delete('1.0', END)
def refresh_all(self):
pass
def main():
root = Tk()
Vocabulary(root)
root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()
def on_closing():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
root.destroy
if __name__ == '__main__':
main()
Someone suggested making root a global variable (bad idea) or passing root to the Vocabulary class and saving a reference to it. How do I do that?
Upvotes: 0
Views: 6974
Reputation: 2087
Someone suggested [...] passing root to the Vocabulary class and saving a reference to it.
Well, you already did so.
In your example, you passed root as an argument upon creating the instance of Vocabulary
:
Vocabulary(root)
Which you can then use as master
in your code because it is the name of your argument.
def __init__(self, master):
In your case, your root is now self.master
:
self.master = master
So you can safely remove self.root = root
and use self.master
as a reference to root.
EDIT (response to comment)
I think it would be a better idea to make on_closing
a method of Vocabulary
, like this you can access the root through self.master
. Also, it seems like the problem is that you forgot the parentheses after destroy
to actually execute the function. Working code:
# Vocabulary.py
# GUI program to manage unknown words
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
class Word:
def __init__(self, wordorphrase, explanation, translation, example):
self.wordorphrase = wordorphrase
self.explanation = explanation
self.example = example
self.translation = translation
class Vocabulary(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.master = master
self.master.resizable(width = False, height = False)
self.master.title("Vocabulary")
self.create_widgets()
self.words = []
def create_widgets(self):
self.buttons_frame = Frame(self.master)
self.buttons_frame.grid(row = 10, sticky = W)
self.search_frame = Frame(self.master)
self.search_frame.grid(row = 1, sticky = W, columnspan = 2)
self.comboBox = ttk.Combobox(self.search_frame,
width = 3)
self.comboBox.grid(row = 0, column = 14, sticky = W)
self.btn_Add = Button(self.buttons_frame,
text = 'Add',
command = self.add_item)
self.btn_Add.grid(row = 0, sticky = W)
self.btn_Remove = Button(self.buttons_frame,
text = 'Remove',
command = self.remove_item)
self.btn_Remove.grid(row = 0, column = 1, sticky = W)
self.btn_Edit = Button(self.buttons_frame,
text = 'Edit',
command = self.edit_item)
self.btn_Edit.grid(row = 0, column = 2, sticky = W)
self.btn_Save = Button(self.buttons_frame,
text = 'Save',
command = self.save_item)
self.btn_Save.grid(row = 0, column = 3, sticky = W)
self.btn_Refresh = Button(self.buttons_frame,
text = 'Refresh',
command = self.refresh_all)
self.btn_Refresh.grid(row = 0, column = 4, sticky = W)
self.lblSearch = Label(self.search_frame, text = 'SEARCH: ')
self.lblSearch.grid(row = 0, column = 5, sticky = W)
self.txt_Search = Text(self.search_frame,
height = 1,
width = 70)
self.txt_Search.grid(row = 0, column = 6, columnspan = 3, sticky = W)
self.lblWordsOrPhrases = Label(self.master, text = 'WORDS/PHRASES:')
self.lblWordsOrPhrases.grid(row = 2, column = 0)
self.lblWordOrPhrase = Label(self.master, text = 'Word or phrase:')
self.lblWordOrPhrase.grid(row = 2, column = 1, sticky = W)
self.listBox = Listbox(self.master,
selectmode='multiple',
height = 34,
width = 38)
self.listBox.grid(row = 3, column = 0, rowspan = 7, sticky = W)
self.txt_WordOrPhrase = Text(self.master,
height = 1,
width = 40)
self.txt_WordOrPhrase.grid(row = 3, column = 1, sticky = N)
self.lblExplanation = Label(self.master, text = 'Explanation:')
self.lblExplanation.grid(row = 4, column = 1, sticky = W)
self.txt_Explanation = Text(self.master,
height = 10,
width = 40)
self.txt_Explanation.grid(row = 5, column = 1, sticky = N)
self.lblTranslation = Label(self.master, text = 'Translation:')
self.lblTranslation.grid(row = 6, column = 1, sticky = W)
self.txt_Translation = Text(self.master,
height = 10,
width = 40)
self.txt_Translation.grid(row = 7, column = 1, sticky = N)
self.lblExamples = Label(self.master, text = 'Example(s):')
self.lblExamples.grid(row = 8, column = 1, sticky = W)
self.txt_Example = Text(self.master,
height = 10,
width = 40)
self.txt_Example.grid(row = 9, column = 1, sticky = S)
def get_word(self):
return self.txt_WordOrPhrase.get('1.0', '1.0 lineend')
def get_explanation(self):
return self.txt_Explanation.get('1.0', '1.0 lineend')
def get_translation(self):
return self.txt_Translation.get('1.0', '1.0 lineend')
def get_example(self):
return self.txt_Example.get('1.0', '1.0 lineend')
def add_item(self):
w = Word(self.get_word(), self.get_explanation(), self.get_translation(), self.get_example())
self.words.append(w)
self.listBox.insert(END, w.wordorphrase)
self.clear_all()
def remove_item(self):
self.listBox.delete(ANCHOR)
self.words.remove()
def edit_item(self):
pass
def save_item(self):
pass
def clear_all(self):
self.txt_WordOrPhrase.delete('1.0', END)
self.txt_Explanation.delete('1.0', END)
self.txt_Translation.delete('1.0', END)
self.txt_Example.delete('1.0', END)
def refresh_all(self):
pass
def on_closing(self):
if messagebox.askokcancel("Quit", "Do you want to quit?"):
self.master.destroy()
def main():
root = Tk()
gui = Vocabulary(root)
root.protocol("WM_DELETE_WINDOW", gui.on_closing)
root.mainloop()
if __name__ == '__main__':
main()
Upvotes: 3