Reputation: 133
I have been trying to call the function showframe which takes two aurgument. When i call it from Button command in HomePage it shows an error. TypeError: showframe() missing 1 required positional argument: 'frame_name'. I can't understand why? As I called by class name so it should automatically get self, then frame_name will get the SignIn class. But thats not happening.
class Culpture(Frame):
def __init__(self, root):
Frame.__init__(self, root)
fhome = HomePage(root)
fsignin = SignIn(root)
self.showframe(fhome)
fhome.grid(row=0, column=0, sticky='nsew')
fsignin.grid(row=0, column=0, sticky='nsew')
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
def showframe(self, frame_name):
frame_name.tkraise()
class HomePage(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
Label(self, text="Homepage").grid()
Button(self, text='SignIn', command=lambda: Culpture.showframe(SignIn), width=20).grid()
If I do this way,
Button(self, text='SignIn', command=lambda: Culpture.showframe(parent, SignIn), width=20).grid()
then it shows another error message.TypeError: tkraise() missing 1 required positional argument: 'self' So I tried to look some question I got one which is close to my solutionPython/Tkinter Event Argument Issue
but not same. If I try another way
Button(self, text='SignIn', command=lambda: Culpture.showframe(parent, SignIn(parent)), width=20).grid()
then it shows no error but button does not open the new frame.
class SignIn(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
Label(self, text="SignIn").grid()
Button(self, text='Submit', width=20).grid()
So it would be really helpfull if any of you can help me out.
Upvotes: 0
Views: 474
Reputation: 811
You are doing things the wrong way. Ideally, you are supposed to make different classes for different pages which will make the code less messy.
So, make a different class for SignIn and a different one for home.
Following is written in python3:
import tkinter as tk
from tkinter import *
class Culpture(tk.Tk):
def __init__(self,*args,**kwargs):
tk.Tk.__init__(self,*args,**kwargs)
F1=tk.Frame(self)
F1.pack(side="top",fill="both",expand=True)
F1.grid_rowconfigure(0,weight=1)
F1.grid_columnconfigure(0,weight=1)
self.frames={}
for F in (Home,SignIn): # Looping between the pages: Home, SignIn (if they are interconnected through buttons)
frame=F(F1,self) # If they are all not interconnected, make different loops for different sets all containg the same element Home
self.frames[F]=frame
frame.grid(row=0,column=0,sticky="nsew")
self.show_frame(Home)
def show_frame(self,cont):
frame=self.frames[cont]
frame.tkraise()
class Home(tk.Frame): # Home page
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
label=Label(self,text="Home",foreground="blue")
label.pack(pady=10,padx=10)
signB=Button(self,text="SignIn",command=lambda:controller.show_frame(SignIn),foreground="snow", background="blue")
signB.pack()
#trajectory.tkinter.tix.balloon
class SignIn(tk.Frame): # SignIn
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
label=Label(self,text="Enter datails",foreground="red")
label.pack(pady=10,padx=10)
home=Button(self,text="Home",command=lambda:controller.show_frame(Home),foreground="snow", background="red")
home.pack()
root=Culpture()
root.mainloop()
Let me know, if this does not work. Also,to add more pages:
If they are interconnected- add the names of the classes to the same loop.
If they are connected to some page in common- make a new lop, with the names.
Upvotes: 1
Reputation: 385980
Somewhere in your code you need to create an instance of Culpture
. You need to use that instance to call show_frame
. When you do that, the instance will be automatically passed as the self
parameter, and the argument you pass will be frame_name
.
culpture = Culpture(root)
...
culpsure.show_frame(fsignin)
You didn't show where you create the instance of Culpture
so it's hard to be any more specific than that.
Upvotes: 1