Nested Class factory with tkinter

前端 未结 2 462
野的像风
野的像风 2020-12-17 23:53

I\'m trying to build a script for import in my future projects. That Script should create some tk.Frames in a tk.Frame and let me edit the created ones in a main

2条回答
  •  有刺的猬
    2020-12-18 00:19

    One solution to this problem, I think, as I don't fully understand your question, but this here was my solution:

    import tkinter as tk
    from tkinter import Frame,Button
    
    class BaseClass(tk.Frame):
        def __init__(self, master):
            tk.Frame.__init__(self, master)
            self.master = master
            self.pack()
    
    
    class Holder_frame(tk.Frame):
        def __init__(self, master, frames=2):
            tk.Frame.__init__(self, master)
            self.master = master
            self.frame_names = []
            for i in range(frames):
                Holder_frame.create_frames("F"+str(i+1), self)
    
        @classmethod
        def create_frames(cls, name, master):
            setattr(cls, name, tk.Frame(master))
    
    if __name__ == "__main__":
        root = tk.Tk()
        def raise1():
            print(type(Holder_frame.F1))
        def raise2():
            print(type(Holder_frame.F2))
    
        holder=Holder_frame(root,frames=2)
        holder.grid(row=1,column=0)
        b1 = tk.Button(root, text='1', command=raise1)
        b1.grid(row=0,column=0)
        b2 = tk.Button(root, text='2', command=raise2)
        b2.grid(row=0,column=1)
        print(Holder_frame.__dict__.items())
    
        root.mainloop()
    

    The use of setattr allows one to add variables to the class, just like if you were to type a function into the code. This allows you to access frames from outside the class as somewhat of a "global variable"

    I used a file to test if it work outside as an imported module too:

    # main.py
    from nested_class import Holder_frame
    import tkinter as tk
    
    root = tk.Tk()
    holder=Holder_frame(root,frames=1000)
    holder.grid(row=1,column=0)
    print(Holder_frame.__dict__.items())
    
    root.mainloop()
    

    I hope this answers your question,

    James

    EDIT:

    After thinking there is, what I think, to be a cleaner system for what you want. With the code from this post one can see that your my written system could be replaced by a ttk.Notebook, and by removing the top bar by using style.layout('TNotebook.Tab', []), one can see that you would get a frame widget that could have frame widgets inside of it:

    import tkinter as tk
    import tkinter.ttk as ttk
    
    class multiframe_example:
        def __init__(self, master):
            self.master = master
    
            style = ttk.Style()
            style.layout('TNotebook.Tab', [])   
            notebook = ttk.Notebook(self.master)
            notebook.grid(row=0, column=0)
    
            self.master.grid_rowconfigure(0, weight=1)
            self.master.grid_columnconfigure(0, weight=1)
    
            tab1 = tk.Frame(self.master,  width=500, height=500, background="green")
            tab2 = tk.Frame(self.master,  width=500, height=500)
            tab3 = tk.Frame(self.master,  width=500, height=500)
    
    
            notebook.add(tab1)
            notebook.add(tab2)
            notebook.add(tab3)
    
            notebook.select(0) # select tab 1
            notebook.select(1) # select tab 2
            notebook.select(2) # select tab 3
    
    def main():
        root = tk.Tk()
        root.geometry("500x500")
        multiframe_example(root)
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    

    Hope this code can support you and does as you would like!

提交回复
热议问题