Python Forum

Full Version: create and insert a new frame on top of another frame
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have an idea and I want to realize it on my little project in tkinter with python 3.6
I'd like to be told how I'm going to start doing this

I want to create a frame or canvas, and when I click on a button "add_sub_frame": a sub frame is created and inserted into the parent frame.
Then, when I click again on the button "add_sub_frame", another subframe is created and added above the subframe previously created.
and this operation is repeated each time I click on the button "add_sub_frame"
at the end, I would have as result an infinity of sub frames that add one above the other in the frame or canvas parent

I thought about: Canvas.create_window (x, y, option, ...)
I would like to have some help
thank you
I struggle to understand why anybody would want to write something like this, but it should be fairly straightforward. It's even possible to give each Frame a random color. Here's how I would imagine somebody doing it:
from tkinter import *
import random

def randomColor ():
    randomRed = ("00" + random.randint(0, 255))[-2]
    randomGreen = ("00" + random.randint(0, 255))[-2]
    randomBlue = ("00" + random.randint(0, 255))[-2]
    return "#{}{}{}".format(randomRed, randomGreen, randomBlue)

class RandomColorNestedFramesApp:

    def __init__(self, master):
        self.master = master
        self.master.geometry("1024x1024+50+50")
        self.bgFrame = Frame(self.master, bg = randomColor())
        self.addFrameButton = Button(self.bgFrame, text = "add sub-frame", bg = "#FF00CC", fg = "black", font = "Times 11", command = self.addDaughterFrame)
        self.addFrameButton.place(relx = 0, rely = 0, relwidth = 0.25, relheight = 0.07)
        self.frameList = []

    def addDaughterFrame (self):
        if self.frameList == []:
            self.frameList.append(Frame(self.bgFrame, bg = randomColor()))

        else:
            self.frameList.append(Frame(self.frameList[-2], bg = randomColor()))

        self.frameList[-1].place(relx = 0.2, rely = 0.2, relwidth = 0.96, relheight = 0.96)

if __name__ == "__main__":
    root = Tk()
    theApp = RandomColorNestedFramesApp(root)
    root.mainloop()
Give it a try and let me know how it works. We definitely can't sell this to Microsoft for millions of dollars but I had fun writing it.

That first attempt was rather hastily thrown together, bad random color function included. This code actually works:
from tkinter import *
import random
 
def randomColor ():
    randomRed = ("00" + hex(random.randint(0, 255))[2:])[-2]
    randomGreen = ("00" + hex(random.randint(0, 255))[2:])[-2]
    randomBlue = ("00" + hex(random.randint(0, 255))[2:])[-2]
    return "#{}{}{}".format(randomRed, randomGreen, randomBlue)
 
class RandomColorNestedFramesApp:
 
    def __init__(self, master):
        self.master = master
        self.master.geometry("1024x1024+50+50")
        self.bgFrame = Frame(self.master, bg = randomColor())
        self.bgFrame.place(relx = 0, rely = 0, relwidth = 1, relheight = 1)
        self.addFrameButton = Button(self.bgFrame, text = "add sub-frame", bg = "#FF00CC", fg = "black", font = "Times 11", command = self.addDaughterFrame)
        self.addFrameButton.place(relx = 0, rely = 0, relwidth = 0.25, relheight = 0.07)
        self.frameList = []
 
    def addDaughterFrame (self):
        if len(self.frameList) < 2:
            self.frameList.append(Frame(self.bgFrame, bg = randomColor()))
 
        else:
            self.frameList.append(Frame(self.frameList[-2], bg = randomColor()))
 
        self.frameList[-1].place(anchor = "center", relx = 0.5, rely = 0.5, relwidth = 0.96, relheight = 0.96)
 
if __name__ == "__main__":
    root = Tk()
    theApp = RandomColorNestedFramesApp(root)
    root.mainloop()
I have actually used this technique (and It was a perfect fit at the time) if you make sure that the sizes and placement are the same, and you use tkinter lift and lower you can actually create a very pleasing effect.
Hi keames

Here a little snippet to play with:
import tkinter as tk
import random

APP_TITLE = "Frame Stack"
APP_XPOS = 50
APP_YPOS = 50
APP_WIDTH = 800
APP_HEIGHT = 800


class Application(object):

    def __init__(self, main_win):
        self.main_win = main_win
        
        self.build()
        
    def build(self):
        self.frame_stack = list()
        self.stack_pointer = 0
        
        self.main_frame = tk.Frame(self.main_win)
        self.main_frame.pack(fill='both', expand=True)
        self.main_frame.columnconfigure(0, weight=1)
        self.main_frame.rowconfigure(0, weight=1)
        
        button_frame = tk.Frame(self.main_frame)
        button_frame.grid(row=1, column=0, pady=4)

        self.stack_level_var = tk.StringVar()
        tk.Label(button_frame, bg='white', width=4, relief='sunken', bd=1,
            textvariable=self.stack_level_var
            ).pack(side='left', padx=10)
            
        tk.Button(button_frame, text="Up",
            command=self.button_up).pack(side='left')
        tk.Button(button_frame, text="Down",
            command=self.button_down).pack(side='left', padx=(2, 20))
        tk.Button(button_frame, text="Add",
            command=self.add_frame).pack(side='left')
        tk.Button(button_frame, text="Exit",
            command=self.main_win.destroy).pack(side='left')
        
        self.add_frame()
        
    def add_frame(self):
        level_frame = tk.Frame(self.main_frame, bg=self.random_color())
        level_frame.grid(row=0, column=0, sticky='news')
        level_frame.lift()
        self.frame_stack.append(level_frame)
        self.stack_pointer = len(self.frame_stack)-1
        self.stack_level_var.set(self.stack_pointer)  
        #self.show_level_frame()
        #self.stack_pointer += 1

    def button_up(self):
        self.stack_navigator('up')

    def button_down(self):
        self.stack_navigator('down')
    
    def stack_navigator(self, direction):
        if direction == 'up':
            if self.stack_pointer < len(self.frame_stack)-1:
                self.stack_pointer += 1
        elif direction == 'down':
            if self.stack_pointer > 0:
                self.stack_pointer -= 1
        
        self.show_level_frame()       
        print(self.stack_pointer, len(self.frame_stack), direction)   
    
    def show_level_frame(self):
                 
        self.stack_level_var.set(self.stack_pointer)        
        self.frame_stack[self.stack_pointer].lift()
                        
    def random_color (self):
        random_red = ("00" + hex(random.randint(0, 255))[2:])[-2]
        random_green = ("00" + hex(random.randint(0, 255))[2:])[-2]
        random_blue = ("00" + hex(random.randint(0, 255))[2:])[-2]
        return "#{}{}{}".format(random_red, random_green, random_blue)

           
def main():
    main_win = tk.Tk()
    main_win.title(APP_TITLE)
    main_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    main_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    
    app = Application(main_win)
    
    main_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
:-)
thanks for all information