form bug when switching frames - python

I'm designing a login screen for my chat application. As I don't have much information about switching frames, I'm looking at the code here and edit for my project accordingly. For now, I want the "Page 2" to be shown when the credentials are entered correctly. However, when I enter the nickname and password correctly, nickname form remains in the second screen and it looks messed up like in the screenshoot I uploaded. Screenshot
How can I solve this problem? The code is below:
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, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
F.grid_propagate(self)
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, width=500, height=500)
self.controller = controller
db = MySQLdb.connect(host="localhost", user="root", passwd="", db="members")
cursor = db.cursor()
label = tk.Label(self, text="Nickname:")
label.place(x=140, y=150)
user_id = tk.Entry()
user_id.place(x=210, y=150)
label_2 = tk.Label(self, text="Password:")
label_2.place(x=140, y=200)
password = tk.Entry(self, show="*")
password.place(x=210, y=200)
def auth_login(event=None):
id = user_id.get()
pswd = password.get()
cursor.execute(
"SELECT nickname, password FROM chatmembers WHERE nickname='{}' AND password='{}' ".format(id, pswd))
if cursor.fetchone():
controller.show_frame("PageTwo")
else:
messagebox.showerror("Wrong credentials", "Either nickname or password is wrong. Please try again.")
login_button = tk.Button(self, text="Log In", command=auth_login, height=2, width=20)
login_button.place(x=195, y=250)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent, width=500, height=500)
self.controller = controller
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.place(x=100, y=200)
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=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()

Related

(python tkinter) pages with class, variable passed to other page, cant use as label : PY_VAR0

I had a problem with passing a variable from one page to the other, its works now, but if I want to use it on a label, it writes PA_VAR0. I read that ".get()" should be used in that case, but it still doesn't work that way. (with .get() it don't even passes the variable). I tried to set a new variable with tk.StringVar() function, but it still didn't work
import tkinter as tk
from tkinter import ttk
class example(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.shared_data = {
"variable": tk.StringVar()
}
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 (page1, page2):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(page1)
def get_page(self, page_class):
return self.frames[page_class]
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class page1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = ttk.Label(self, text="first page")
label.grid(row=0, column=4, padx=10, pady=10)
button1 = ttk.Button(self, text="turn page",
command=lambda: self.pageturn())
button1.grid(row=3, column=1, padx=10, pady=10)
def pageturn(self):
self.controller.shared_data["variable"] = 'string i wanna pass'
print("variable set here: ", self.controller.shared_data["variable"])
self.controller.show_frame(page2)
class page2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = ttk.Label(self, text=self.controller.shared_data["variable"])
label.grid(row=0, column=4, padx=10, pady=10)
label = ttk.Label(self, text=self.controller.shared_data["variable"].get())
label.grid(row=1, column=4, padx=10, pady=10)
button3 = ttk.Button(self, text=self.controller.shared_data["variable"],
command=lambda: print(self.controller.shared_data["variable"]))
button3.grid(row=8, column=10, padx=10, pady=10)
button2 = ttk.Button(self, text="if fuction sees variable",
command=lambda: self.ifok())
button2.grid(row=9, column=10, padx=10, pady=10)
def ifok(self):
if self.controller.shared_data["variable"] == 'string i wanna pass':
print("ok")
app = example()
app.mainloop()
You overwrite self.controller.shared_data["variable"] by a string inside pageturn():
self.controller.shared_data["variable"] = 'string i wanna pass'
You should use .set() instead:
self.controller.shared_data["variable"].set('string i wanna pass')
Full updated code:
import tkinter as tk
from tkinter import ttk
class example(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.shared_data = {
"variable": tk.StringVar()
}
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 (page1, page2):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(page1)
def get_page(self, page_class):
return self.frames[page_class]
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class page1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = ttk.Label(self, text="first page")
label.grid(row=0, column=4, padx=10, pady=10)
button1 = ttk.Button(self, text="turn page",
command=lambda: self.pageturn())
button1.grid(row=3, column=1, padx=10, pady=10)
def pageturn(self):
self.controller.shared_data["variable"].set('string i wanna pass') ### changed = to .set()
print("variable set here: ", self.controller.shared_data["variable"].get()) ### called .get()
self.controller.show_frame(page2)
class page2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = ttk.Label(self, textvariable=self.controller.shared_data["variable"]) ### changed text to textvariable
label.grid(row=0, column=4, padx=10, pady=10)
label = ttk.Label(self, text=self.controller.shared_data["variable"].get())
label.grid(row=1, column=4, padx=10, pady=10)
button3 = ttk.Button(self, textvariable=self.controller.shared_data["variable"], ### changed text to textvariable
command=lambda: print(self.controller.shared_data["variable"].get()))
button3.grid(row=8, column=10, padx=10, pady=10)
button2 = ttk.Button(self, text="if fuction sees variable",
command=lambda: self.ifok())
button2.grid(row=9, column=10, padx=10, pady=10)
def ifok(self):
if self.controller.shared_data["variable"].get() == 'string i wanna pass': ### called .get()
print("ok")
app = example()
app.mainloop()

Tkinter: How to grid inside of a class?

I am trying to add a variable inside of class, and also grid it with the e1.grid() command. I can create the variable inside of the class but for some reason I can't grid the variable and I can't grid text either. Is there any way to solve this problem?
import tkinter as tk
from tkinter import font as tkfont
from tkinter import Entry
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, PageOne):
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):
'''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="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"))
button1.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=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()
e1 = Entry(self)
e1.grid(row=0, column=1)
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
you can't use pack with grid together.
'''
e1 = Entry(self).pack()
#e1.grid(row=0, column=1)
'''
so...
import tkinter as tk
from tkinter import font as tkfont
from tkinter import Entry
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, PageOne):
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):
'''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="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"))
button1.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=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()
e1 = Entry(self).pack()
#e1.grid(row=0, column=1)
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
update
if you want use grid method you must grid for all widgets in the relative page
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=controller.title_font)
label.grid(row=0, column=0)
button = tk.Button(self, text="Go to the start page",command=lambda: controller.show_frame("StartPage"))
button.grid(row=0, column=1)
e1 = Entry(self)
e1.grid(row=1, column=0)

Trying to code a password checker and generator using Tkinter

So far, I have the generator working but I can't get the tkinter to display the variable for the generated password, it only comes up in the console. Once I have the password checker working as well, I need that to be able to change variable as well, please help, here is a copy of my code
from tkinter import *
import tkinter as tk
from tkinter import font as tkfont
import random
import time
global strength
global gen
strength = 0;
gen = '[password will be here]';
global mypw
mypw = '';
def generate():
alphabet = "abcdefghijklmnopqrstuvwxyz"
pw_length = 8
mypw = ""
for i in range(pw_length):
next_index = random.randrange(len(alphabet))
mypw = mypw + alphabet[next_index]
# replace 1 or 2 characters with a number
for i in range(random.randrange(1,3)):
replace_index = random.randrange(len(mypw)//2)
mypw = mypw[0:replace_index] + str(random.randrange(10)) + mypw[replace_index+1:]
# replace 1 or 2 letters with an uppercase letter
for i in range(random.randrange(1,3)):
replace_index = random.randrange(len(mypw)//2,len(mypw))
mypw = mypw[0:replace_index] + mypw[replace_index].upper() + mypw[replace_index+1:]
print(mypw)
gen = mypw;
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
label = tk.Label(self, text="Passowrd program", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Check your password strength",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Generate a new password",
command=lambda:[generate(),time.sleep(0.1),controller.show_frame("PageTwo")])
button3 = tk.Button(self, text="quit", command=close)
button1.pack()
button2.pack()
button3.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label1 = tk.Label(self, text="Check your password", font=controller.title_font)
label1.pack(side="top", fill="x", pady=10)
entry = tk.Entry(self, bd =6)
button2 = tk.Button(self, text="Back",
command=lambda: controller.show_frame("StartPage"))
label2 = tk.Label(self, text="Strength:", font=controller.title_font)
label3 = tk.Label(self, text=strength, font=controller.title_font)
entry.pack()
button2.pack()
label2.pack()
label3.pack()
password = list(entry.get())
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
'''while 0 == 0:
gen = mypw;'''
var = StringVar()
var.set(gen)
tk.Frame.__init__(self, parent)
self.controller = controller
label1 = tk.Label(self, text="Generate a password", font=controller.title_font)
label1.pack(side="top", fill="x", pady=10)
label2 = tk.Label(self, textvariable=var, font=controller.title_font)
button = tk.Button(self, text="Back",
command=lambda: controller.show_frame("StartPage"))
label2.pack()
button.pack()
def close():
messagebox.showinfo("BYE", "Thank you")
time.sleep(1)
app.destroy()
#def check_generate():
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
generate()
so, that's my code, I hope someone can help, it would be really useful, thanks
The problem is that you aren't updating the var StringVar that is used to display the generated password. Here's a version of your code which fixes that, but it is a little messy. There are a couple of other problems with your code, but I'll let you discover those. ;)
from tkinter import *
import tkinter as tk
from tkinter import font as tkfont
import random
import time
global strength
global gen
strength = 0
gen = '[password will be here]'
global mypw
mypw = ''
def generate(pwvar):
alphabet = "abcdefghijklmnopqrstuvwxyz"
pw_length = 8
mypw = ""
for i in range(pw_length):
next_index = random.randrange(len(alphabet))
mypw = mypw + alphabet[next_index]
# replace 1 or 2 characters with a number
for i in range(random.randrange(1,3)):
replace_index = random.randrange(len(mypw)//2)
mypw = mypw[0:replace_index] + str(random.randrange(10)) + mypw[replace_index+1:]
# replace 1 or 2 letters with an uppercase letter
for i in range(random.randrange(1,3)):
replace_index = random.randrange(len(mypw)//2,len(mypw))
mypw = mypw[0:replace_index] + mypw[replace_index].upper() + mypw[replace_index+1:]
print(mypw)
gen = mypw
pwvar.set(gen)
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
label = tk.Label(self, text="Password program", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Check your password strength",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Generate a new password",
command=lambda:[generate(self.controller.frames['PageTwo'].var),time.sleep(0.1),controller.show_frame("PageTwo")])
button3 = tk.Button(self, text="quit", command=close)
button1.pack()
button2.pack()
button3.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label1 = tk.Label(self, text="Check your password", font=controller.title_font)
label1.pack(side="top", fill="x", pady=10)
entry = tk.Entry(self, bd =6)
button2 = tk.Button(self, text="Back",
command=lambda: controller.show_frame("StartPage"))
label2 = tk.Label(self, text="Strength:", font=controller.title_font)
label3 = tk.Label(self, text=strength, font=controller.title_font)
entry.pack()
button2.pack()
label2.pack()
label3.pack()
password = list(entry.get())
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
self.var = StringVar()
self.var.set(gen)
tk.Frame.__init__(self, parent)
self.controller = controller
label1 = tk.Label(self, text="Generate a password", font=controller.title_font)
label1.pack(side="top", fill="x", pady=10)
label2 = tk.Label(self, textvariable=self.var, font=controller.title_font)
button = tk.Button(self, text="Back",
command=lambda: controller.show_frame("StartPage"))
label2.pack()
button.pack()
def close():
messagebox.showinfo("BYE", "Thank you")
time.sleep(1)
app.destroy()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
generate()
Here's a slightly better way. Instead of having that dodgy list as the callback function in PageTwo we make a proper method, generate_password. Not only is it easier to read & to debug, by doing it this way we don't need to pass the password StringVar to generate, instead we can get generate to return the new password and then set the StringVar insidegenerate_password.
I've also gotten rid of that useless mypw global. I removed the messy from tkinter import *, and I added the tkinter.messagebox so that your close function will work.
import tkinter as tk
from tkinter import font as tkfont
import tkinter.messagebox as messagebox
import random
import time
global strength
global gen
strength = 0
gen = '[password will be here]'
def generate():
alphabet = "abcdefghijklmnopqrstuvwxyz"
pw_length = 8
mypw = ""
for i in range(pw_length):
next_index = random.randrange(len(alphabet))
mypw = mypw + alphabet[next_index]
# replace 1 or 2 characters with a number
for i in range(random.randrange(1,3)):
replace_index = random.randrange(len(mypw)//2)
mypw = mypw[0:replace_index] + str(random.randrange(10)) + mypw[replace_index+1:]
# replace 1 or 2 letters with an uppercase letter
for i in range(random.randrange(1,3)):
replace_index = random.randrange(len(mypw)//2,len(mypw))
mypw = mypw[0:replace_index] + mypw[replace_index].upper() + mypw[replace_index+1:]
print(mypw)
return mypw
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
label = tk.Label(self, text="Password program", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button1 = tk.Button(self, text="Check your password strength",
command=lambda: controller.show_frame("PageOne"))
button2 = tk.Button(self, text="Generate a new password",
command=self.generate_password)
button3 = tk.Button(self, text="quit", command=close)
button1.pack()
button2.pack()
button3.pack()
def generate_password(self):
password = generate()
password_var = self.controller.frames['PageTwo'].var
password_var.set(password)
time.sleep(0.1)
self.controller.show_frame("PageTwo")
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label1 = tk.Label(self, text="Check your password", font=controller.title_font)
label1.pack(side="top", fill="x", pady=10)
entry = tk.Entry(self, bd =6)
button2 = tk.Button(self, text="Back",
command=lambda: controller.show_frame("StartPage"))
label2 = tk.Label(self, text="Strength:", font=controller.title_font)
label3 = tk.Label(self, text=strength, font=controller.title_font)
entry.pack()
button2.pack()
label2.pack()
label3.pack()
password = list(entry.get())
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
self.var = tk.StringVar()
self.var.set(gen)
tk.Frame.__init__(self, parent)
self.controller = controller
label1 = tk.Label(self, text="Generate a password", font=controller.title_font)
label1.pack(side="top", fill="x", pady=10)
label2 = tk.Label(self, textvariable=self.var, font=controller.title_font)
button = tk.Button(self, text="Back",
command=lambda: controller.show_frame("StartPage"))
label2.pack()
button.pack()
def close():
messagebox.showinfo("BYE", "Thank you")
time.sleep(1)
app.destroy()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
generate()

How to display a function output/result in another window/frame using tkinter

i'm currently trying to creat a small accounting program where the user should type his earnings and expanses and the program should count it and display the differnt transactions in an secound frame. Im stuck at this point: So far ive created 6 frames where the user can switch between with buttons.
When the user click on the button "first transaction" he can entry a ammount and after he click on validate the ammount is displaying under the button.
But i want that the ammount is display at the frame "transaction overview"
After hours spending with searching the web i couln't find a way to display a functions output on a secound frame/window in the App. Thanks for your helf.
class Finanzapp(tk.Tk):
def get_page(self, classname):
for page in self.frames.values():
if str(page.__class__.__name__) == classname:
return page
return None
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Finanz Manager V2")
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, PageThree, Pagefour, Pagefive):
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):
self.controller = controller
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button1 = ttk.Button(self, text="erste Buchung",
command=lambda: controller.show_frame(PageOne)) # add a page
button1.pack()
button2 = ttk.Button(self, text="Konten",
command=lambda: controller.show_frame(PageTwo)) # add a page
button2.pack()
button3 = ttk.Button(self, text="neue Buchung",
command=lambda: controller.show_frame(PageThree)) # add a page
button3.pack()
button4 = ttk.Button(self, text="Kategorien",
command=lambda: controller.show_frame(Pagefour)) # add a page
button4.pack()
button5 = ttk.Button(self, text="Übersicht",
command=lambda: controller.show_frame(Pagefive)) # add a page
button5.pack()
button6 = ttk.Button(self, text="Diagramm",
command=lambda: controller.show_frame(StartPage)) # add a page
button6.pack()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="erste Buchung", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button1 = ttk.Button(self, text="zurück",
command=lambda: controller.show_frame(StartPage)) # add a page
button1.pack()
def calc():
monthly_earning = float(m_earning.get())
labelresult1 = Label(self, text='gebucht: € %.2f' % monthly_earning).pack()
label1 = Label(self, text='Enter the amount').pack()
m_earning=StringVar()
earning=Entry(self, textvariable=m_earning).pack()
buttoncalc=Button(self,text='Buchen', command=calc).pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
def get_page(self,PageOne):
def print_it(self):
page_one = self.controller.get_page("PageOne")
value = page_one.monthly_m_earning.get()
labelresult2 = Label(self, text='gebucht: € %.2f' % value).pack()
self.controller = controller
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Konten", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button1 = ttk.Button(self, text="zurück",
command=lambda: controller.show_frame(StartPage))
button1.pack()

Calling Tkinter frame controller from function rather then button command

So I have the following, which works perfectly:
import tkinter as tk
class App(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 (LoginPage, ProjPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, rowspan=12, columnspan=6, sticky="nsew")
self.show_frame(LoginPage)
def show_frame(self, c):
frame = self.frames[c]
frame.tkraise()
class LoginPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
Btn = tk.Button(self, text="Sign In", command=lambda: controller.show_frame(ProjPage))
But I want that last button command to be in a separate function, so I can do some evaluations first:
Btn = tk.Button(self, text="Sign In", command=self.signIn)
def signIn(self):
# do some stuff here
self.controller.show_frame(ProjPage)
This doesn't work; regardless if I try to pass the controller, or use a lambda, nothing seems to work >.<
What am I not getting?
You don't seem to initialize controller in self. Put it there in __init__ of LoginPage, like so:
self.controller = controller
my program has a page(main page) that has 5 radio button in it and a button "ok",and I have 5 other Frame. I want my program to go to these frames after clicking the "ok" ( based on the chosen radio button).
when the "ok" is clicked it will call a lambda and get the value of chosen radiobutton and based on this valuefind the string (veg) which represent the name of the page.
here is the code:
import tkinter as tk
from tkinter import ttk
from win32print import StartPage
class KBSapp(tk.Tk):
def init(self, *args, **kwargs):
tk.Tk.init(self, *args, **kwargs)
tk.Tk.iconbitmap(self,default="icon.ico")
tk.Tk.wm_title(self, "Diseases and pests of vegetable crops")
container = tk.Frame(self, width=200, height=200, bg='black')
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,carrot,celery, potato, wheat, bean):
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, width=0, height=20)
label.pack()
button2 = ttk.Button(self, command=lambda : okclick(v) ,text='OK', width=25)
button2.pack( )
v = tk.IntVar( )
self.option1 = ttk.Radiobutton(self, text="Carrot", variable=v, value=1);self.option1.pack( )
self.option2 = ttk.Radiobutton(self, text="Celery", variable=v, value=2);self.option2.pack( )
self.option3 = ttk.Radiobutton(self, text="potato", variable=v, value=3);self.option3.pack( )
self.option4 = ttk.Radiobutton(self, text="wheat", variable=v, value=4);self.option4.pack( )
self.option5 = ttk.Radiobutton(self, text="bean", variable=v, value=5);self.option5.pack( )
v.set(1) # initializing the choice
def okclick(v):
global veg
input1=v.get( )
if input1==1:
veg="carrot"
if input1==2:
veg='celery'
if input1==3:
veg='potato'
if input1==4:
veg='wheat'
if input1==5:
veg='bean'
print(veg)
class carrot(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button3 = ttk.Button(self, command=lambda : controller.show_frame(celery) , text='celery', width=25)
button3.pack( )
class celery(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button4 = ttk.Button(self, command=lambda : controller.show_frame(potato) , text='potato', width=25)
button4.pack( )
class potato(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button4 = ttk.Button(self, command=lambda : controller.show_frame(wheat) , text='wheat', width=25)
button4.pack( )
class wheat(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button4 = ttk.Button(self, command=lambda : controller.show_frame(bean) , text='bean', width=25)
button4.pack( )
class bean(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button4 = ttk.Button(self, command=lambda : controller.show_frame(StartPage) , text='StartPage', width=25)
button4.pack( )
app = KBSapp( )
app.mainloop( )

Categories