pass entry value from one class to another class tkinter python - python-3.x

I want to pass entry values from one class to another using the get() method and i dont know how. Thanks in advance
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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.x=tk.StringVar()
self.y=tk.StringVar()
self.key=tk.IntVar()
self.key.set(0)
self.frames = {}
for F in (StartPage, PageOne, PageTwo, LoggedIn, Balance):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Banking Application", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="User Login",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Create Account",
command=lambda: controller.show_frame("PageTwo"))
button1.pack()
button2.pack()
This is from where i want to pass the userid entry value to Balance class
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Login Page", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
#user id entry block
tk.Label(self,text="UserID").pack(side="top", fill="x", pady=4)
self.userid=tk.Entry(self,textvariable=self.controller.x)
self.userid.pack(side="top", fill="x", pady=6)
#password entry block
tk.Label(self,text="Password").pack(side="top", fill="x", pady=4)
self.password=tk.Entry(self,textvariable=self.controller.y)
self.password.pack(side="top", fill="x", pady=6)
self.submit=tk.Button(self, text="SUBMIT",
command=self.login)
self.submit.pack();
button = tk.Button(self, text="Back to Main Menu",
command=lambda: controller.show_frame("StartPage"))
button.pack()
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
def getname(self):
name=self.controller.x.get()
print (name)
return name
def login(self):
getname(self);
for x in range(0,listsize):
if(self.controller.x.get()==files[x]):
print("welcome %s"%(self.controller.x.get()))
if(self.controller.y.get()==keys[x]):
bal=open(self.controller.x.get()+'.txt','r')
currbal=int(bal.read())
print("login success")
self.controller.key.set(1)
# print(self.controller.key=1)
self.controller.show_frame("LoggedIn");
break
else:
print("Invalid credentials")
How to pass userid from pageone to this class
class Balance(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Balance Enquiry", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
username = PageOne.getname(self);
print(username)
if(self.controller.key==1):
print(username)
bal=open(username+'.txt','r')
currbal=int(bal.read())
label1 = tk.Label(self, text=currbal)
label1.pack(side="top", fill="x", pady=10)
###########
button = tk.Button(self, text="Go to the savings page",
command=lambda: controller.show_frame("LoggedIn"))
button.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()

Related

I want to make a GUI but i get this error: self.frame.grid(row=0, column=0, sticky="nsew") AttributeError: 'function' object has no attribute 'grid'

Sorry about the layout of this question, my first time working with stackoverflow posts.
I want to make a GUI for Tic Tac Toe (Game menu). And have the abillity to put buttons where ever i want in the GUI so i used Grid.
import tkinter as tk
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 (MainWindow, Game, Difficulty):
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 MainWindow(tk.Tk):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Welcom to TIC TAC TOE", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = tk.Button(self, text="Start",
command=lambda: controller.show_frame(Game))
button1.pack()
button2 = tk.Button(self, text="Diffeculty",
command=lambda: controller.show_frame(Difficulty))
button2.pack()
button3 = tk.Button(self, text="Quit", command=self.Quit)
button3.pack()
label1 = tk.Label(self, text="Made by VindictaOG")
label1.pack()
def Quit(self):
exit()
class Game(tk.Tk):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
button1 = tk.Button(self, text="New Game")
button1.pack()
button2= tk.Button(self, text="Back to homescreen",
command=lambda: controller.show_frame(MainWindow))
button2.pack()
class Difficulty(tk.Tk):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
button1 = tk.Button(self, text="1V1", command=lambda: controller.show_frame(MainWindow))
button1.pack()
button2 = tk.Button(self, text="Back to homescreen",
command=lambda: controller.show_frame(Game))
button2.pack()
gui = SeaofBTCapp()
gui.mainloop()
But when i use grid i get this error:
Traceback (most recent call last):
File "/home/ivar/PycharmProjects/J1B2Afvink6/BKE.py", line 82, in <module>
gui = SeaofBTCapp()
File "/home/ivar/PycharmProjects/J1B2Afvink6/BKE.py", line 27, in __init__
frame.grid(row=0, column=0, sticky="nsew")
TypeError: wm_grid() got an unexpected keyword argument 'row'
I tried it with pack but that would not work, does someone know how to fix this?
Should inherit from tk.Frame instead of tk.Tk for MainWindow, Game and Difficulty. Also StartPage is not defined. #acw1668
Using (tk.Frame, tk.Tk) instead of just (tk.Tk) solved the problem.

Is there a way to change window title with multiple frames

I'm trying to create a window with multiple frames in tkinter. But the window title remains the same for any active frame.
The code is used for reference is here.
I tried to add
self.container.title(title)
in respective Pages classes. but the window get the title which was specified the latest.
'''
Solution from...
https://stackoverflow.com/questions/7546050/switch-between-two-frames-in-tkinter
'''
import tkinter as tk # python 3
from tkinter import font as tkfont # python 3
#import Tkinter as tk # python 2
#import tkFont as tkfont # python 2
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.controller.title("Start Page")
label = tk.Label(self, text="This is the start page", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Go to Page Two",
command=lambda: controller.show_frame("PageTwo"))
button1.pack()
button2.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.controller.title("Page One")
label = tk.Label(self, text="This is page 1", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.controller.title("Page Two")
label = tk.Label(self, text="This is page 2", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
Here I expected it to have title of the window to change whenever the frame changed but it prints the title as "Page Two" for entire time even I jump from one frame to another.
Yes, you can use the parameter page_name to change the title of the app when a frame changes
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
self.title(page_name) # update the app title

Passing user data after login between windows in Python tkinter

I have problem with passing dictionary between windows in Tkinter. After successful login I want to create dictionary, in which data of the logged-in user will be stored. I would like dictionary to be available in every window of the program. I tried to do it this way:
import tkinter as tk # python 3
from tkinter import font as tkfont # python 3
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
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, Window2, Window1):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.discUserInfo = {}
label = tk.Label(self, text="Start Page", font=controller.title_font)
label.pack()
label2 = tk.Label(self, text="Login:")
label2.pack()
label2.place()
self.e1 = tk.Entry(self)
self.e1.pack()
self.e1.place()
label3 = tk.Label(self, text="Password:")
label3.pack()
label3.place()
self.e2 = tk.Entry(self, show="*")
self.e2.pack()
self.e2.place()
button1 = tk.Button(self, text="Login",
command=self._login_btn_clicked,width = 25)
button1.pack()
button1.place()
def _login_btn_clicked(self):
### after verifying the login data in database, it creates a dictionary with the user's data ( userId,name,lastName ...)
self.discUserInfo['name'] ='Joe'
self.discUserInfo['userId'] =1
self.controller.show_frame("Window1")
class Window2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="window 2", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Tset",
command=self.onClick, width=42,bg="#C44041")
button1.pack()
button3 = tk.Button(self, text="Back",
command=lambda : controller.show_frame("Window1"), width=42, bg="#C44041")
button3.pack()
def onClick(self):
print (self.discUserInfo)
class Window1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="window 1", font=controller.title_font)
label.pack()
button1 = tk.Button(self, text="Next",
command=lambda: controller.show_frame("Window2"), width=42)
button1.pack()
button1.place()
##################################################
button2 = tk.Button(self, text="Test",
command=self.getAlocationData, width=42)
button2.pack()
button2.place()
def getAlocationData(self):
print(self.discUserInfo)
if __name__ == "__main__":
app = SampleApp()
app.geometry('{}x{}'.format(800, 650))
app.mainloop()
But python shows this error:
print(self.discUserInfo) AttributeError: 'Window1' object has no
attribute 'discUserInfo'.
I tried to create a global dictionary.But working only in some one windows.
If you create the dictionary in the controller (SampleApp) then all other windows could access it via self.controller.discUserInfo. The following is not tested, but something like this may work.
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
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.discUserInfo = {}
self.frames = {}
for F in (StartPage, Window2, Window1):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="Start Page", font=controller.title_font)
label.pack()
label2 = tk.Label(self, text="Login:")
label2.pack()
label2.place()
self.e1 = tk.Entry(self)
self.e1.pack()
self.e1.place()
label3 = tk.Label(self, text="Password:")
label3.pack()
label3.place()
self.e2 = tk.Entry(self, show="*")
self.e2.pack()
self.e2.place()
button1 = tk.Button(self, text="Login",
command=self._login_btn_clicked,width = 25)
button1.pack()
button1.place()
def _login_btn_clicked(self):
### after verifying the login data in database, it creates a dictionary with the user's data ( userId,name,lastName ...)
self.controller.discUserInfo['name'] ='Joe'
self.controller.discUserInfo['userId'] =1
self.controller.show_frame("Window1")
class Window2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="window 2", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Tset",
command=self.onClick, width=42,bg="#C44041")
button1.pack()
button3 = tk.Button(self, text="Back",
command=lambda : controller.show_frame("Window1"), width=42, bg="#C44041")
button3.pack()
def onClick(self):
print (self.controller.discUserInfo)
class Window1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="window 1", font=controller.title_font)
label.pack()
button1 = tk.Button(self, text="Next",
command=lambda: controller.show_frame("Window2"), width=42)
button1.pack()
button1.place()
##################################################
button2 = tk.Button(self, text="Test",
command=self.getAlocationData, width=42)
button2.pack()
button2.place()
def getAlocationData(self):
print(self.controller.discUserInfo)
if __name__ == "__main__":
app = SampleApp()
app.geometry('{}x{}'.format(800, 650))
app.mainloop()

Need help figuring out how to title the different pages in tkinter created differently without having the same title for all pages?

I am a beginner in programming in python and I have a question. With the code shown below, is it possible to give each class (which represent a different page) a different title and not a title to all the pages at once? I have looked everywhere and have been unable to find an answer. Thank you!
import tkinter as tk
# from tkinter import *
# Activate the line above when a message box is needed
class Start(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)
self.title("Application")
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage, PageOne):
# To add a new page, define the class below and then add the frame to the For Loop above
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, controller):
frame = self.frames[controller]
frame.tkraise()
def get_page(self, page_class):
return self.frames[page_class]
# This is the end of the baseline and the code for each page is below:
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
Name = StringVar()
Password = StringVar()
def show_credentials(event):
instructions = tk.Label(self, text="Credentials: ")
instructions.grid(row=5, column=3, sticky="E")
names = Name.get()
passwords = Password.get()
names = tk.Label(self, text=names, bg="red", fg="white")
passwords = tk.Label(self, text=passwords, bg="Red", fg="white")
names.grid(row=6, column=3, sticky="E")
passwords.grid(row=7, column=3, sticky="E")
credentials = tk.Button(self, text="Creds")
credentials.bind("<Button-1>", show_credentials)
credentials.grid(row=4, column=3, sticky="E")
def login(event):
controller.show_frame(PageOne)
log = tk.Button(self, text="Log In")
log.bind("<Button-1>", login)
log.grid(row=4, column=4, sticky="E")
# A class can be created to compare data entered to a list to identify the user and log him/her in
welcome = tk.Label(self, text="Welcome!")
welcome.grid(row=0, column=2, sticky="E")
username = tk.Label(self, text="Username: ")
username.grid(row=2, column=2, sticky='E')
password_label = tk.Label(self, text="Password: ")
password_label.grid(row=3, column=2, sticky="E")
username_entry = tk.Entry(self, textvariable=Name)
username_entry.grid(row=2, column=3, sticky="E")
password_entry = tk.Entry(self, textvariable=Password, show="*")
password_entry.grid(row=3, column=3, sticky="E")
cancel = tk.Button(self, text="Exit", command=quit)
cancel.grid(row=4, column=2, sticky="E")
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This page is currently under Development")
label.grid(row=0, column=0, sticky="E")
switchpage1 = tk.Button(self, text="Back", command=lambda: controller.show_frame(StartPage))
switchpage1.grid(row=1, column=0, sticky="E")
root = Start()
root.mainloop()
Here is a way to title a different window:
import tkinter as tk
root = tk.Tk()
window1 = tk.Toplevel(root)
window1.wm_title("window 1")
root.mainloop()

Tkinter multiple frames/'pages': using canvas images

I would like to employ multiple frames in a GUI, where the page switches depending on the button clicked. I know that there's several threads already about this, and I've been looking at this one.
However, for my pages, I need different images on canvasses within each of my frames, so that when I raise a different frame, it comes with a new canvas and a new image on that canvas. I've tried a lot but I don't know how to get it to work so that the canvasses appear with their images.
Here's what I have so far, mostly copying from above link:
import tkinter as tk # python3
TITLE_FONT = ("Helvetica", 18, "bold")
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
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 = {}
self.frames["StartPage"] = StartPage(parent=container, controller=self)
self.frames["PageOne"] = PageOne(parent=container, controller=self)
self.frames["PageTwo"] = PageTwo(parent=container, controller=self)
self.frames["StartPage"].grid(row=0, column=0, sticky="nsew")
self.frames["PageOne"].grid(row=0, column=0, sticky="nsew")
self.frames["PageTwo"].grid(row=0, column=0, sticky="nsew")
self.show_frame("StartPage")
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self._canvas = tk.Canvas(parent, bg='white', width=900, height=3517, scrollregion=(0, 2800, 100, 800))
self._photo = tk.PhotoImage(file='images/homegraphic.gif')
self._canvas.create_image(0, 0, image=self._photo, anchor='nw')
label = tk.Label(self, text="This is the start page", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Go to Page One",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Go to Page Two",
command=lambda: controller.show_frame("PageTwo"))
button1.pack()
button2.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 2", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.pack()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
How do I get the canvas image to appear? I've spent a long time trying to figure this out and would appreciate any help!
The problem is here:
self._canvas = tk.Canvas(parent, ...)
Everything within a page needs to be a child of the page or one of its descendants.
It needs to be this:
self._canvas = tk.Canvas(self, ...)

Resources