我试图教我自己如何使用tkinter,我通过youtube发现了一个有用的代码,我并不完全理解.如果有人能帮助我理解它,我将不胜感激.标记我不理解的事情**
import tkinter as tk # why not from tkinter import? ** class SampleApp(tk.Tk): tk.TK** def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) # the container is where we'll stack a bunch of frames # on top of each other, then the one we want visible # will be raised above the others 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, PageTwo): page_name = F.__name__ frame = F(container, self) ** self.frames[page_name] = frame ** # put all of the pages in the same location; # the one on the top of the stacking order # will be the one that is visible. frame.grid(row=0, column=0, sticky="nsew") self.show_frame("StartPage") def show_frame(self, page_name): '''Show a frame for the given page name''' frame = self.frames[page_name] frame.tkraise() ** class StartPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) ** self.controller = controller ** label = tk.Label(self, text="This is the start page", font=TITLE_FONT) label.pack(side="top", fill="x", pady=10) button1 = tk.Button(self, text="Go to Page One", command=lambda: controller.show_frame("PageOne")) button2 = tk.Button(self, text="Go to Page Two", command=lambda: controller.show_frame("PageTwo")) button1.pack() button2.pack()
Bryan Oakley.. 17
import tkinter as tk # why not from tkinter import? **
为什么不from tkinter import *
呢?因为这是错误的做法.全球进口不好.由于我不理解的某些原因,Tkinter教程倾向于以错误的方式执行.
这as tk
部分的原因是你可以做tk.Frame
而不是Tkinter.Frame
,使代码更容易打字,更容易阅读.它完全是可选的.
class SampleApp(tk.Tk):
tk是导入的tkinter模块的名称.Tk
是该模块中表示根窗口的类的名称.每个tkinter应用程序都必须有一个根窗口.通过将其置于其中SampleApp
,这将创建此窗口小部件的子类 - 具有其他功能的副本.
没有必要继承tk.Tk
.您可以继承tk.Frame
,任何其他tkinter小部件,甚至object
.这是个人偏好.选择使一些事情变得更容易,有些事情变得更难.
container = tk.Frame(self)
上面创建了一个Frame
小部件的实例,它将用作其他"页面"的容器.这些"页面"将在此容器中堆叠在一起.
frame = F(container, self)
F
是循环变量.循环遍历类列表,因此每次循环F
都将表示一个类.F(...)
创建一个类的实例.这些类(StartPage
,PageOne
,PageTwo
),都需要两个参数:窗口小部件,这将是这个类的父,和一个对象,将服务器作为控制器(从UI图案借用的一个术语模型/视图/控制器).
代码行创建类的实例(它本身是Frame
小部件的子类),并临时将框架分配给局部变量frame
.
通过传递self
第二个("controller")参数,这些新的类实例将能够调用SampleApp
类对象中的方法.
self.frames[page_name] = frame
这样可以保存对字典中刚刚创建的帧的引用.字典的关键是页面名称(或更准确地说,是类的名称).
这是show_frame
方法只能从类的名称确定实际页面窗口小部件的方式.
frame.tkraise()
几乎所有的GUI工具包 - 包括tkinter - 都有"堆叠顺序"的概念:事物堆叠的顺序.有些工具包可能称之为z顺序.如果两个或多个窗口小部件堆叠在一起(此代码通过将所有页面放在同一行和列中来完成),则堆栈顶部的窗口小部件通常是可见的窗口小部件.
tkraise
是一种Frame
对象的方法,它将帧提升到堆叠顺序的顶部.在这行代码中,frame
引用其中一个页面的一个特定实例.
tk.Frame.__init__(self, parent)
因为每个页面都是类的子tk.Frame
类,所以它调用父类的构造函数.这是初始化构成实际框架窗口小部件的所有内部结构所必需的.尽管a Frame
可以采用许多选项,但是此代码只选择发送一个 - 对另一个小部件的引用,该小部件将充当此新小部件的父级.
self.controller = controller
上面的代码只是"记住" controller
传入的变量的值.在这种情况下,它controller
是应用程序.通过保存它,此类可以调用SampleApp
对象上的方法.
注意:问题中的代码来自一个复制此答案代码的教程:https://stackoverflow.com/a/7557028/7432.我是原始代码的作者,但不是本教程的作者.原始答案是与此代码相关的其他问题的链接.
import tkinter as tk # why not from tkinter import? **
为什么不from tkinter import *
呢?因为这是错误的做法.全球进口不好.由于我不理解的某些原因,Tkinter教程倾向于以错误的方式执行.
这as tk
部分的原因是你可以做tk.Frame
而不是Tkinter.Frame
,使代码更容易打字,更容易阅读.它完全是可选的.
class SampleApp(tk.Tk):
tk是导入的tkinter模块的名称.Tk
是该模块中表示根窗口的类的名称.每个tkinter应用程序都必须有一个根窗口.通过将其置于其中SampleApp
,这将创建此窗口小部件的子类 - 具有其他功能的副本.
没有必要继承tk.Tk
.您可以继承tk.Frame
,任何其他tkinter小部件,甚至object
.这是个人偏好.选择使一些事情变得更容易,有些事情变得更难.
container = tk.Frame(self)
上面创建了一个Frame
小部件的实例,它将用作其他"页面"的容器.这些"页面"将在此容器中堆叠在一起.
frame = F(container, self)
F
是循环变量.循环遍历类列表,因此每次循环F
都将表示一个类.F(...)
创建一个类的实例.这些类(StartPage
,PageOne
,PageTwo
),都需要两个参数:窗口小部件,这将是这个类的父,和一个对象,将服务器作为控制器(从UI图案借用的一个术语模型/视图/控制器).
代码行创建类的实例(它本身是Frame
小部件的子类),并临时将框架分配给局部变量frame
.
通过传递self
第二个("controller")参数,这些新的类实例将能够调用SampleApp
类对象中的方法.
self.frames[page_name] = frame
这样可以保存对字典中刚刚创建的帧的引用.字典的关键是页面名称(或更准确地说,是类的名称).
这是show_frame
方法只能从类的名称确定实际页面窗口小部件的方式.
frame.tkraise()
几乎所有的GUI工具包 - 包括tkinter - 都有"堆叠顺序"的概念:事物堆叠的顺序.有些工具包可能称之为z顺序.如果两个或多个窗口小部件堆叠在一起(此代码通过将所有页面放在同一行和列中来完成),则堆栈顶部的窗口小部件通常是可见的窗口小部件.
tkraise
是一种Frame
对象的方法,它将帧提升到堆叠顺序的顶部.在这行代码中,frame
引用其中一个页面的一个特定实例.
tk.Frame.__init__(self, parent)
因为每个页面都是类的子tk.Frame
类,所以它调用父类的构造函数.这是初始化构成实际框架窗口小部件的所有内部结构所必需的.尽管a Frame
可以采用许多选项,但是此代码只选择发送一个 - 对另一个小部件的引用,该小部件将充当此新小部件的父级.
self.controller = controller
上面的代码只是"记住" controller
传入的变量的值.在这种情况下,它controller
是应用程序.通过保存它,此类可以调用SampleApp
对象上的方法.
注意:问题中的代码来自一个复制此答案代码的教程:https://stackoverflow.com/a/7557028/7432.我是原始代码的作者,但不是本教程的作者.原始答案是与此代码相关的其他问题的链接.