I'm trying to insert an Entry
field in my tkinter
-based GUI.
It has three different "pages" as classes with buttons etc, but the Entry
field doesn't work.
I want to put the entry field in the last page (class PageTwo
). Then I just want to click one of the check buttons and I would be OK if the entered text would show as print, or in another text field in the GUI.
Update: I changed the entry code to controller.wordde = Entry(self)
and made a button print(controller.wordde.get())
The error code I get is:
Traceback (most recent call last):
File "C:\x\g_4.py", line 147, in <module>
app = SeaofBTCapp()
File "C:\x\g_4.py", line 40, in __init__
frame = F(container, self)
File "C:\x\g_4.py", line 141, in __init__
wordde.grid(row=3, column=1)
NameError: name 'wordde' is not defined
This is the code:
from tkinter import *
import tkinter as tk
import csv
import random
import sys
z = random.randint(1,50)
with open('vokabelnsemicolon.csv') as csvfile:
readCSV = csv.reader(csvfile, delimiter=';')
delist = []
enlist = []
for row in readCSV:
eng = row[1]
deu = row[0]
delist.append(deu)
enlist.append(eng)
LARGE_FONT= ("Verdana", 12)
class SeaofBTCapp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button = tk.Button(self, text="German -> English",
command=lambda: controller.show_frame(PageOne))
button.pack()
button2 = tk.Button(self, text="-> English -> German",
command=lambda: controller.show_frame(PageTwo))
button2.pack()
#German -> English
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="German -> English", font=LARGE_FONT)
label.grid(row=0, column=0)
button1 = tk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.grid(row=1, column=1)
button2 = tk.Button(self, text="English -> German",
command=lambda: controller.show_frame(PageTwo))
button2.grid(row=2, column=1)
button3 = tk.Button(self, text="Check",
command=None)
button3.grid(row=4, column=1)
#text field for entry box
Label(self, text='"'+enlist[z]+'"'+ ' in english is: ').grid(row=3, column=0)
#entry field
worden = Entry(self)
worden.grid(row=3, column=1)
#English -> German
class PageTwo(tk.Frame):
def checkybutton(self):
print('checkbutton!')
def checkybutton2(self):
print(controller.wordde.get())
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="English -> German", font=LARGE_FONT)
label.grid(row=0, column=0)
button1 = tk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.grid(row=1, column=1)
button2 = tk.Button(self, text="German -> English",
command=lambda: controller.show_frame(PageOne))
button2.grid(row=2, column=1)
#text field for entry box
Label(self, text='"'+delist[z]+'"'+ ' in german is: ').grid(row=3, column=0)
button3 = tk.Button(self, text="checkbutton",
command=self.checkybutton)
button3.grid(row=4, column=1)
button4 = tk.Button(self, text="checkbutton 2",
command=self.checkybutton2)
button4.grid(row=4, column=0)
#entry field
controller.wordde = Entry(self)
wordde.grid(row=3, column=1)
txt = Text(self, width=35, height=1, wrap=WORD)
txt.grid(row=5, columnspan=2, sticky=W)
app = SeaofBTCapp()
app.mainloop()
You have to store the entry somewhere, to be able to refer to it later.
For your code, it seems the best place to store it is in the controller, as it is accessible on all pages:
instead of worden = Entry(self)
use:
controller.worden = Entry(self)
That will store a reference to your entry instance in the controller object. Later you can use controller.worden.get()
to retrieve the value:
print(controller.worden.get())
EDIT: To clarify - controller
is an instance of the SeaofBTCapp
class created here:
app = SeaofBTCapp()
That instance is passed to the other classes' __init__
here:
for F in (StartPage, PageOne, PageTwo):
frame = F(container, self) # self is the controller
Now, since you will need access to the controller
in other methods that are not __init__
, you have to also store a reference to the controller in the instances of those classes.
Change __init__
in the StartPage
, PageOne
and PageTwo
classes to do this:
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
#.... rest of the method here ...
That means each page istance has a reference to the controller
stored as an attribute. Now, in the methods of those classes that are not __init__
, you can access that object by using self.controller
:
def checkybutton2(self):
print(self.controller.wordde.get())