Tkinter网格管理器中的Python类
我在使用Tkinter的GRID布局管理器或者自定义类,或者两者都有问题。很可能是两者都有。以下是我的代码:
import sys
from tkinter import
def main():
app = App()
app.master.title("Sample application")
app.mainloop()
class App(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid(sticky=N+S+E+W)
top = self.winfo_toplevel()
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
self.rowconfigure(1, weight=1)
self.columnconfigure(0, weight=1)
self.__createWidgets()
def __createWidgets(self):
self.f1 = Frame(self, height=100, width=200,
bg='green')
self.f1.grid(row=0, column=0, sticky=E+W)
self.f2 = Frame( self, bg= "yellow", height=100, width=200 ) ############################# CHANGE to self.f2 = myTestFrame( self )
self.f2.grid(row=1, sticky = N+S+E+W)
self.f3 = Frame( self, bg = "cyan", height = 100, width = 200 )
self.f3.grid(row=2, sticky = E+W)
self.quitButton = Button ( self, text="Quit", command=self.quit )
self.quitButton.grid(row=4, column=0, columnspan=100,
sticky=E+W)
class myTestFrame( Frame ):
def __init__( self, parent):
Frame.__init__(self, None)
self.myText = Text( self )
self.myText.grid()
#self.testFrame = Frame ( self, bg = "white", height = 100, width = 300 )
#self.testFrame.grid()
if __name__ == "__main__":
main()
`
现在问题来了:这段代码基本上能完成我想要的功能。这里有三个框架,顶部框架是self.f1
,中间框架是self.f2
,底部框架是self.f3
,还有一个简单的退出按钮。顶部(第0行)和底部(第2行)框架可以水平调整大小,而中间框架的行(第1行,第0列)负责水平和垂直的调整大小。到目前为止一切都很好……直到我尝试实现自己的类myTestFrame
。
每当我试图在self.f2
中放入一个Text()
小部件时,事情就变得混乱了。它显示了默认的文本小部件,但我的调整大小就出问题了,GRID的布局也很疯狂。这是怎么回事呢?
编辑!!!
unutbu的回答确实帮助我解决了类的问题。现在GRID管理器可以正确地将文本小部件放入中间框架self.f2
中,但是,即使我在myText.grid(sticky = N+S+E+W)
中设置了sticky,它也没有正确扩展。所以我想到了以下几点:
1) 通过在class App
的def __init__
构造函数中设置根窗口可调整大小,我让应用窗口的第一行和第零列获得了所有的调整大小空间,使用了self.rowconfigure( 1, weight = 1)
和self.columnconfigure( 0, weight = 1)
。
2) 现在框架self.f2
被放在第1行,它将获得所有的调整大小,使用self.f2.grid(N+S+E+W)
。
3) 现在我在这个自定义框架中放入一个text()
小部件,并通过self.myText.grid(sticky = N+S+E+W)
设置它占据这个框架的所有空间。
但是text()
小部件并没有填满self.f2
!当我不使用自定义类时,正常情况下使用sticky = N+S+E+W
属性是可以正常工作的。我这样想对吗?
1 个回答
在使用 Frame.__init__
时,需要传入一个父级对象:
class myTestFrame( tk.Frame ):
tk.Frame.__init__(self, parent, *args, **kwargs)
下面是一个可以运行的例子:
import sys
import Tkinter as tk
E=tk.E
W=tk.W
N=tk.N
S=tk.S
def main():
app = App()
app.master.title("Sample application")
app.mainloop()
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid(sticky=N+S+E+W)
top = self.winfo_toplevel()
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
self.rowconfigure(1, weight=1)
self.columnconfigure(0, weight=1)
self.__createWidgets()
def __createWidgets(self):
self.f1 = tk.Frame(self, height=100, width=200, bg='green')
self.f1.grid(row=0, sticky=E+W)
self.f2 = myTestFrame(self, bg='yellow', height=100, width=200)
self.f3 = tk.Frame( self, bg = "cyan", height = 100, width = 200)
self.f3.grid(row=2, sticky=E+W)
self.quitButton = tk.Button(self, text="Quit", command=self.quit)
self.quitButton.grid(row=4, column=0, sticky=E+W)
class myTestFrame( tk.Frame ):
def __init__(self, parent, cnf={}, **kw):
tk.Frame.__init__(self, parent, cnf, **kw)
self.grid(row=1, sticky=N+S+E+W)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.myText = tk.Text(self)
self.myText.grid(row=0, sticky=N+S+E+W)
if __name__ == "__main__":
main()