0

I want to get the split screen, where if i click a button in the left screen then frame should be shown in the right screen. So i used Panedwindow with 2 different frames (rightframe and leftframe). Gave buttons in the leftframe (button1 and button2). If i click the button1 then Frame1 (class Frame1) should be shown in the rightframe and if i click the button2 then Frame2 (class Frame2) should be shown in the rightframe so used raiseFrame to change the frame accordingly but getting below error if i click the button.

import tkinter as tk
from tkinter import *
from tkinter import ttk,Tk, BOTH, Menu
  
def raiseFrame(frame):
    frame.tkraise()

class Main(tk.Tk):

    def __init__(self):
        
        tk.Tk.__init__(self)
        
        m = PanedWindow(height=500, width=1000)
        m.pack(side=tk.RIGHT,fill = tk.Y)

        leftframe = Frame(m)
        m.add(leftframe)

        button1 =tk.Button(leftframe, text="first frame",command=lambda: raiseFrame(Frame1))                    
        button1.pack(side = tk.TOP, expand=1)
        
        button2 =tk.Button(leftframe, text="2nd frame",command=lambda: raiseFrame(Frame2))                   
        button2.pack(side = tk.TOP, expand=1)


        rightframe= Frame(m, bg="green")
        m.add(rightframe)


class Frame1(tk.Frame):

    def __init__(self):
        tk.Frame.__init__(self, parent)
        
        label = tk.Label(rightframe, text="1st FRAME").pack(side = tk.LEFT,fill = tk.BOTH) 
            

class Frame2(tk.Frame):

    def __init__(self):
        tk.Frame.__init__(self,parent)

        label = tk.Label(rightframe, text="2nd FRAME").pack(side = tk.LEFT,fill = tk.BOTH)
        
app = Main()
app.mainloop()

error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:\Users\New folder\GUI.py", line 23, in <lambda>
    button1 =tk.Button(leftframe, text="first frame",command=lambda: raiseFrame(Frame1))
  File "C:\Users\New folder\GUI.py", line 7, in raiseFrame
    frame.tkraise()
TypeError: tkraise() missing 1 required positional argument: 'self'

Screenshot after changes: enter image description here

Kyle
  • 63
  • 7

1 Answers1

1

You haven't instantiated the class Frame1 and Frame2, you are passing the classes directly and calling tkraise on them. You would have to first create their instances and stack them up.

frame1=Frame1(rightframe)
frame1.grid(row=0,column=0,sticky='nesw')
frame2=Frame2(rightframe)
frame2.grid(row=0,column=0,sticky='nesw')

Then pass the instances to the command

command=lambda: raiseFrame(frame1)
command=lambda: raiseFrame(frame2)

Also, you haven't specified the parent argument in the __init__ function and the Label should have the current frame (self) as the master and not rightframe.

class Frame1(tk.Frame):

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        
        label = tk.Label(self, text="1st FRAME").pack(side = tk.LEFT,fill = tk.BOTH) 

Additionally, I don't see a point in creating 2 different classes just for having a different text in the containing label, you can define a single class something like this

class CustomFrame(tk.Frame):

    def __init__(self, parent, text=''):
        tk.Frame.__init__(self,parent)

        label = tk.Label(self, text=text)
        label.pack(side = tk.LEFT,fill = tk.BOTH)

And have 2 instances of it

frame1=CustomFrame(rightframe,text='1st Frame')
frame2=CustomFrame(rightframe,text='2nd Frame')

UPDATE

Add the following to allow expansion (the concept of weight has been explained well here)

rightframe.rowconfigure(0, weight = 1)
rightframe.columnconfigure(0, weight = 1)
astqx
  • 2,058
  • 1
  • 10
  • 21
  • Thank you so much.. Its working but have a doubt.. sticky='nesw' isn't working, the label wont fill in the entire window.. is it possible to explain on that part. please find the attached screenshot. @AST – Kyle Mar 14 '21 at 14:31