2017-10-28 100 views
0

我试图动态地将子帧添加到主框架小部件。子帧是带有按钮的列,我为子帧创建了一个单独的类,以便将子帧作为列表中的对象,以便稍后可以对其进行更改。实际上,额外列的数量也取决于用户输入。在Tkinter中添加子帧python3

我首先使用网格管理器将小部件添加到主框架,稍后我使用网格将按钮添加到子框架。我希望网格在不同的帧中使用时会实现,但是它表现为子帧类中的网格调用直接在主框架内部而不是在子框内部放置部件。

代码:

import tkinter as tk 

extra_columns = 1 

class App(tk.Tk): 
    def __init__(self, *args, **kwargs): 
     tk.Tk.__init__(self, *args, **kwargs) 

     container = tk.Frame(self) 
     container.grid(sticky="nsew") 
     container.grid_rowconfigure(0, weight=1) 
     container.grid_columnconfigure(0, weight=1) 

     self.frames = {} 
     for F in (MainFrame,): 
      page_name = F.__name__ 
      frame = F(parent=container, controller=self) 
      self.frames[page_name] = frame 
      frame.grid(row=0, column=0, sticky="nsew") 

     self.show_frame("MainFrame") 

    def show_frame(self, page_name): 
     frame = self.frames[page_name] 
     frame.tkraise() 


class MainFrame(tk.Frame): 
    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     self.controller = controller 
     self.subframes = [] 
     self.init_main() 
     self.init_subframes() 

    def init_main(self): 
     self.title = tk.Label(text='Title') 
     self.title.grid(row=0, column = 2) 
     for i in range(1, 3): 
      b = tk.Button(text=str(i)) 
      b.grid(row=i, column=0) 
      c = tk.Button(text=str(i+10)) 
      c.grid(row=i, column=2+extra_columns+1) 

    def init_subframes(self): 
     for i in range(1, extra_columns+1): 
      m = SubFrame(self) 
      self.subframes.append(m) 
      m.grid(row=1, column=2+i, rowspan=5) 


class SubFrame(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 
     for i in range(1, 6): 
      b = tk.Button(text="extra"+str(i), command=lambda: print("button \ 
pressed")) 
      b.grid(row=i, column=0) 


root = App() 
root.mainloop() 

为了记录:我显示主框架(App类内)的方式从教程采取pythonprogramming.net,是我真正的代码也可使用。

谢谢!

+1

你是否知道'Label','Button'等的第一个参数是父窗口或框架,它应该包含标签或按钮? –

+1

谢谢,将master = ...添加到我所有的网格任务中解决了我的问题! –

回答

1

Bryan的评论所述,在创建窗口小部件(框架,按钮,标签等)对象时,除非明确将框架对象作为父对象传递,否则认为根窗口是父窗口。

如果你想在一个框架的基础上管理几何图形,你需要指定该框架的父窗口。

检查下面的代码:

import tkinter as tk 

#creates a window object named root, this object is the default parent for ever widget object 
root = tk.Tk() 

#creates a frame that is a child of object named 'root' 
mainFrame = tk.Frame(master=root) 

#creates a frame that is a child of 'mainFrame' 
subFrame_mainFrame = tk.Frame(mainFrame) 

#creates a button that is a child of 'subFrame' 
button_subFrame_mainFrame_root = tk.Button(master=subFrame) 

#creates a button that is a child of default, which is 'root' in this case 
button_root = tk.Button() 

#creates a button that is a child of mainFrame 
button_mainFrame = tk.Button(mainFrame) 

可以管理主窗口或任何的框架的内容独立的几何形状,给你正确分配框架的孩子把它当成父。

Here是模块化管理几何图形的一个例子。

+1

感谢您的详细示例,我将master = self作为参数添加到每个网格调用中,并且所有的孩子都可以正确对齐! –

+1

@CelThys作为参考,你实际上不需要说'master =',因为每个小部件的第一个参数被认为是小部件的父代或“主”。只要说'Button(parent,text = ........)'就足够了。 –