0

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.

2
  • what is SignIn? Commented Apr 19, 2018 at 2:58
  • That doesn't give an error and also it doesn't open signin frame. Commented Apr 20, 2018 at 1:41

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

6 Comments

import tkinter as tk & from tkinter import *... why?
In some very rare cases, when the program is very large, you may need it for organisation. It's not mandatory at all. I just do it for most of my programs to avoid errors (unless it lags..).
This code works. But I can't understand why I have to inherit Tk() class in Culpture instead of Frame class? Though I use a dictionary for frame class why I passed frames class in showframe self.show_frame(Home) instead of dictionary name?
@AbdullahAlMubin: you don't have to inherit from the Tk class. You can inherit from Frame instead. It's just that you have to have an instance of Tk somewhere, and since this is the "main" frame, there's no need to create a frame and then place it in an empty window.
@EshitaShukla Can you explain though using a dictionary for frame class why I passed Home class in showframe self.show_frame(Home) instead of dictionary name self.show_frame(frames[Home]) ?
|
1

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.

1 Comment

Here showframe doesn't get reference of 'fsingin'. class HomePage(Frame): def __init__(self, parent): f1 = Culpture(parent) Frame.__init__(self, parent) Label(self, text="Homepage").grid() Button(self, text='SignIn', command=lambda: f1.showframe(fsignin), width=20).grid()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.