2017-09-13 114 views
2

我有一个Tkinter应用程序,我想在框架中包含一些按钮,然后将此框架放置在主窗口中。Tkinter - 包含按钮的类

但是,运行代码只返回一个空窗口。所以我想我错过完全如何建立一个Tkinter应用与模块化类..原子代码:

import Tkinter as tk 

class MainApplication(tk.Frame): 
    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent, *args, **kwargs) 
     self.parent = parent 
     self.navbar = NavBar(self) 
     self.navbar.grid(row=0, column=0) 

class NavBar(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 
     self.parent = parent 
     self.fetchDataBtn = tk.Button(self, text='Fetch data') 
     self.filterDataBtn = tk.Button(self, text='Filter data') 

     self.fetchDataBtn.pack(padx=5, pady=10, side=tk.LEFT) 
     self.filterDataBtn.pack(padx=5, pady=20, side=tk.LEFT) 

def main(): 
    root = tk.Tk() 
    app = MainApplication(root) 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

我这样不知道我错过了。我搜索了但找不到重复的内容(如果它们是某些,可以指出并且我将关闭该主题)。

注意:我使用Python 2.7.10

回答

5

问题是,你不包装(或网格或地方)你的MainApplication实例。 由于您的MainApplication扩展了tk.Frame类,因此它的实例是窗口小部件,因此需要打包到其主窗口中。

def main(): 
    root = tk.Tk() 
    app = MainApplication(root)  <--- here: where does it go in the root? 
    root.mainloop() 

收拾它,它会工作:

app.pack() 
+0

我的首选是在类之外的'init' I/O之后'包装()'。 –

+0

@ReblochonMasque这样做的问题是,您失去了对实例定位方式的控制。如果你想使用'grid'而不是?例如,您希望将同一个小部件的四个实例作为正方形。你在普通的'__init__'的底部写什么? –

+0

谢谢,我完全错过了在根中定位我的框架的观点... –

1

你必须把导航栏父框架中,使用pack,或grid

import Tkinter as tk 

class MainApplication(tk.Frame): 
    def __init__(self, parent, *args, **kwargs): 
     tk.Frame.__init__(self, parent, *args, **kwargs) 
     self.parent = parent 
     self.navbar = NavBar(self) 
     self.navbar.grid(row=0, column=0) 
     self.pack()    # <-- here --------- 

class NavBar(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 
     self.parent = parent 
     self.fetchDataBtn = tk.Button(self, text='Fetch data') 
     self.filterDataBtn = tk.Button(self, text='Filter data') 

     self.fetchDataBtn.pack(padx=5, pady=10, side=tk.LEFT) 
     self.filterDataBtn.pack(padx=5, pady=20, side=tk.LEFT) 

def main(): 
    root = tk.Tk() 
    app = MainApplication(root) 
    # app.pack() # <-- or here for a better control of the placement of several instances 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

贷@RightLeg指点了初步的错误。

+0

为什么会这样呢? –

+0

去哪里?如果你不? –

+0

问题不在于你所描述的。当然,这“解决”了问题......但逻辑不在这里。导航栏的父**是** MainApplication实例,而不是后者的父对象。根据这个逻辑,每个部件的父部件应该是根部...问题(检查我的答案)是'MainApplication'实例需要像其他任何部件一样打包。所以OP的代码不工作的原因是它错过了调用'app.pack()'(或'app.grid()',如果有意义的话)。 –