Posts: 126
Threads: 29
Joined: Aug 2018
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
Posts: 50
Threads: 6
Joined: Apr 2019
Apr-16-2019, 01:53 AM
(This post was last modified: Apr-16-2019, 02:07 AM by keames.)
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()
Posts: 12,036
Threads: 486
Joined: Sep 2016
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.
Posts: 74
Threads: 0
Joined: Mar 2017
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() :-)
Posts: 126
Threads: 29
Joined: Aug 2018
thanks for all information
|