Suppose I have two functions which when called opens up a Frame:
Eg:
from tkinter import *
win = Tk()
class MyFrame(Frame):
def __init__(self, master, **kwargs):
Frame.__init__(self, master,
bg='white' ,**kwargs)
def FuncOne():
frameone = MyFrame(win)
frameone.pack()
lbl = Label(frameone, text="ABC", font='"Serif" 247' , width=win.winfo_screenwidth(), height=win.winfo_screenheight())
lbl.pack(fill=BOTH, expand=True)
def FuncTwo():
frametwo = MyFrame(win)
frametwo.pack()
lbl = Label(frametwo, text="ABC", font='"Serif" 200', width=win.winfo_screenwidth(), height=win.winfo_screenheight())
lbl.pack()
win.mainloop()
How do I call FuncOne and FuncTwo which opens a separate frame each time by using a side arrow key and destroy the frame in FuncOne while calling FuncTwo and vice versa?
The following code provides 2 functions that will create a instance of your MyFrame
class. In this function we will check if the list is empty with if actual_frame:
returns False
when its empty and create an instances of your class. On the bottom of this function wie store this instance in the list actual_frame
. If you run now another time a function if actual_frame:
returns True
and it will destroy
this instances, clear
the list and build a new instance.
from tkinter import *
win = Tk()
class MyFrame(Frame):
def __init__(self, master, **kwargs):
Frame.__init__(self, master,
bg='red' ,**kwargs)
actual_frame=[]
def FuncOne(event):
if actual_frame:
actual_frame[0].destroy()
actual_frame.clear()
frameone = MyFrame(win)
frameone.grid(column=0,row=0)
lbl = Label(frameone, text="ABC", font='"Serif" 24' , width=10, height=15)
lbl.pack(side=TOP,fill=BOTH, expand=True)
actual_frame.append(frameone)
def FuncTwo(event):
if actual_frame:
actual_frame[0].destroy()
actual_frame.clear()
frametwo = MyFrame(win)
frametwo.grid(column=0,row=0)
lbl = Label(frametwo, text="XYZ", font='"Serif" 20', width=10,height=15)
lbl.pack(side=TOP, fill=BOTH, expand=True)
actual_frame.append(frametwo)
win.bind('<Left>', FuncOne)
win.bind('<Right>', FuncTwo)
win.mainloop()
Update In this update I hade made another list in that we store all the functions you like to have. The keys we use here to cycle through the list with a little help oft itertools.cycle
. We call in our new binded function the function that is next or once before in the function list.
from tkinter import *
from itertools import cycle
win = Tk()
class MyFrame(Frame):
def __init__(self, master, **kwargs):
Frame.__init__(self, master,
bg='red' ,**kwargs)
my_funcs=[]
actual_frame=[]
def FuncOne():
if actual_frame:
actual_frame[0].destroy()
actual_frame.clear()
frameone = MyFrame(win)
frameone.grid(column=0,row=0)
lbl = Label(frameone, text="ABC", font='"Serif" 24' , width=10, height=15)
lbl.pack(side=TOP,fill=BOTH, expand=True)
actual_frame.append(frameone)
def FuncTwo():
if actual_frame:
actual_frame[0].destroy()
actual_frame.clear()
frametwo = MyFrame(win)
frametwo.grid(column=0,row=0)
lbl = Label(frametwo, text="XYZ", font='"Serif" 20', width=10,height=15)
lbl.pack(side=TOP, fill=BOTH, expand=True)
actual_frame.append(frametwo)
def FuncThree():
if actual_frame:
actual_frame[0].destroy()
actual_frame.clear()
framethree = MyFrame(win)
framethree.grid(column=0,row=0)
lbl = Label(framethree, text="DEF", font='"Serif" 20', width=10,height=15)
lbl.pack(side=TOP, fill=BOTH, expand=True)
actual_frame.append(framethree)
my_funcs.append(FuncOne)
my_funcs.append(FuncTwo)
my_funcs.append(FuncThree)
cycle_of_funcs = cycle(my_funcs)
def right_way(event):
func = next(cycle_of_funcs)
func()
def left_way(event):
leng = len(my_funcs)
for function in range(leng-1):
func = next(cycle_of_funcs)
func()
win.bind('<Left>', left_way)
win.bind('<Right>', right_way)
win.mainloop()
I just want to leave a comment here that I think it isnt the best way of doing this, but still a possible way. Just to make sure on this answer is space for a OOP solutions [click]
Here are the binds for the arrow keys:
win.bind('<left>', function)
win.bind('<right>', function2)
As for getting rid of each frame, you need someway to figure out whether the other frame exists, and if it does then destroy it.
frameone = None # Initialize it as nothing
frametwo = None # Initialize it as nothing
def FuncOne():
global frameone, frametwo # make it accessible
...
if frametwo != None:
# Get rid of frametwo
frametwo.destroy()
frametwo = None
...
frameone.pack()
def FuncTwo():
global frameone, frametwo # make it accessible
...
if frameone != None:
# Get rid of frameone
frameone.destroy()
frameone= None
...
frametwo.pack()
Basically, what it does is that it sets frameone and frametwo to None. Then, when a certain function is called, it sets frameone/frametwo to a frame object. Then, when the other function is called, it sees that the other frame is not none, so it destroys it and makes it none.
I made a picker function which is an event. There is also a frame count which tells the picker which one should it start. At the start of your function I destroy the other window. Here is my code:
from tkinter import *
win = Tk()
frame = 1
class MyFrame(Frame):
def __init__(self, master, **kwargs):
Frame.__init__(self, master,
bg='white' ,**kwargs)
def FuncOne():
global frameone
try:
frametwo.destroy()
except:
pass
frameone = MyFrame(win)
frameone.pack()
lbl = Label(frameone, text="ABC", font='"Serif" 247' , width=win.winfo_screenwidth(), height=win.winfo_screenheight())
lbl.pack(fill=BOTH, expand=True)
def FuncTwo():
global frametwo
try:
frameone.destroy()
except:
pass
frametwo = MyFrame(win)
frametwo.pack()
lbl = Label(frametwo, text="ABC", font='"Serif" 200', width=win.winfo_screenwidth(), height=win.winfo_screenheight())
lbl.pack()
def picker(event):
global frame
if frame == 1:
frame = 2
FuncOne()
else:
frame = 1
FuncTwo()
win.bind('<Left>', picker)
win.bind('<Right>', picker)
win.mainloop()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.