tkinter的简单介绍
-
首先建立一个frame,类似于框架
-
然后把各个page pack到frame上面,也就是下面code的show_frame
-
显示不同的东西通过页面之间的跳转来实现,从startPage到pageOne,再从pageOne回到startPage
import Tkinter as tk
'''
self: self表示当前的对象。
parent: 表示当前对象的父对象。除了root,tkinter的所有widgets都有一个父widget。
controller: 用来连接几个不同的page(frame)的公共数据。这样的话,每一个page可以
独立的update数据,而不需要调用其他page。如果它需要作用于另一个page(比如通过click
一个buttom,使得另一个页面变成top页面从而可视,这时候就可以用controller来让它可视。
container上面有不同的frame(page).它们被保存在frames里面,而frames属于myFrame,
所以show_frame没有办法像prt一样从myFrame里面拿出来。
startPage其实是继承了container,而不仅仅是tk.Frame. 但是它又要调用show_frame,
所以它的__init__需要两个参数,第一个是parent,第二个其实是连接myFrame的self,用来
调用show_frame。所以会出现 frame = startPage(container, self),因为这个,
controller.show_frame(startPage) 就变成了self.show_frame(startPage),
这样show_frame才会被调用,startPage才会被显示
prt函数只是在startPage打印,而且它不需要使用myFrame的任何属性,所以它可以单独放外面,
我们也可以把它放到myFrame下面,就像myFrame2里面那样。那样的话就成了myFrame2的属性,
所以在startPage里面就要使用controller.prt()
'''
class myFrame1(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side = "top", fill = "both", expand = True) #
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
self.frames = {}
for F in (startPage, pageOne):
frame = F(container, self) #startPage继承了container
frame.grid(row=0, column=0, sticky="nsew")
self.frames[F] = frame
self.show_frame(startPage)
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
def prt():
print "this is test"
class startPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text = "Start Page")
label.pack(pady = 10, padx = 10)
# 在__init__下面,可以写self.controller或者controller,它们是一样的
# 但是在上面的show_frame(不在__init__下),那么就需要self.frames,要不然找不到frames
b1 = tk.Button(self, text = "Page One", command = lambda: self.controller.show_frame(pageOne))
b1.pack()
b2 = tk.Button(self, text = "Print", command = lambda: prt())
b2.pack()
class pageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text = "Page one")
label.pack(pady = 10, padx = 10)
b1 = tk.Button(self, text = "go home", command = lambda: self.controller.show_frame(startPage))
b1.pack()
app1 = myFrame1()
app1.mainloop()
########## This is to show how to put prt inside myFrame, compared with above ###########
import Tkinter as tk
class myFrame2(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side = "top", fill = "both", expand = True) #
container.grid_rowconfigure(0, weight = 1)
container.grid_columnconfigure(0, weight = 1)
self.frames = {}
frame = startPage(container, self) #
frame.grid(row=0, column=0, sticky="nsew")
self.frames[startPage] = frame
self.show_frame(startPage)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
def prt(self):
print "this is test"
class startPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text = "Page one")
label.pack(pady = 10, padx = 10)
b1 = tk.Button(self, text = "go home", command = lambda: controller.show_frame(startPage))
b1.pack()
b2 = tk.Button(self, text = "Print", command = lambda: controller.prt())
b2.pack()
app2 = myFrame2()
app2.mainloop()
# ref:
# http://stackoverflow.com/questions/7300072/inheriting-from-frame-or-not-in-a-tkinter-application
# http://effbot.org/tkinterbook/tkinter-hello-again.htm
# http://stackoverflow.com/questions/17466561/best-way-to-structure-a-tkinter-application
# http://t1174779123.iteye.com/blog/2051485
# http://stackoverflow.com/questions/7546050/switch-between-two-frames-in-tkinter
# http://stackoverflow.com/questions/34301300/tkinter-understanding-how-to-switch-frames