Tkinter类结构(每帧类)与小部件复制有关 [英] Tkinter Class structure (class per frame) issue with duplicating widgets
问题描述
我一直在尝试将OOP与Tkinter一起使用-我正在慢慢到达那里(我认为)...
Ive been trying out OOP for use with Tkinter - Im getting there (I think) slowly...
我想建立一个处理每个帧的结构按其自己的类,包括其所有小部件和功能。也许我从错误的角度出发,但这对我来说是最合乎逻辑的。 -随时告诉我您是否同意!
I wanted to build a structure where each frame is handled by its own class, including all of its widgets and functions. Perhaps I am coming from the wrong angle but that is what makes most logical sense to me. - Feel free to tell me if you agree / disagree!
我知道问题出在什么地方-当我将每个类都称为我的 __ init __
每次运行并构建相关的小部件,无论它们是否已存在于框架中。但是,我能想到的唯一方法是在主类 GUI_Start $ c $的
__ init __
中构建每个框架c>。 -尽管这看起来像是一个杂乱无章的解决方案。
I know why the problem is happening - when im calling each class my __init__
runs everytime and builds the relevant widgets regardless of whether they are already present in the frame. However, the only way I can think of getting round this would be to build each frame in the __init__
of my primary class GUI_Start
. - Although this seems like a messy and un-organised soloution to the problem.
有没有一种方法可以使每个类都负责自己的功能和小部件,但不必每次都构建框架?
Is there a way I can achieve a structure where each class takes care of its own functions and widgets but doesn't build the frame each time?
请参阅以下问题的最小示例:
See below for minimal example of the issue:
from Tkinter import *
class GUI_Start:
def __init__(self, master):
self.master = master
self.master.geometry('300x300')
self.master.grid_rowconfigure(0, weight=1)
self.master.grid_columnconfigure(0, weight=1)
self.win_colour = '#D2B48C'
self.frames = {}
for window in ['win1', 'win2']:
frame = Frame(self.master, bg=self.win_colour, bd=10, relief=GROOVE)
frame.grid(row=0, column=0, sticky='news')
setattr(self, window, frame)
self.frames[window] = frame
Page_1(self.frames)
def Next_Page(self, frames, controller):
controller(frames)
class Page_1(GUI_Start):
def __init__(self, master):
self.master = master
self.master['win1'].tkraise()
page1_label = Label(self.master['win1'], text='PAGE 1')
page1_label.pack(fill=X)
page1_button = Button(self.master['win1'], text='Visit Page 2...', command=lambda: self.Next_Page(self.master, Page_2))
page1_button.pack(fill=X, side=BOTTOM)
class Page_2(GUI_Start):
def __init__(self, master):
self.master = master
self.master['win2'].tkraise()
page2_label = Label(self.master['win2'], text='PAGE 2')
page2_label.pack(fill=X)
page2_button = Button(self.master['win2'], text='Back to Page 1...', command=lambda: self.Next_Page(self.master, Page_1))
page2_button.pack(fill=X, side=BOTTOM)
root = Tk()
gui = GUI_Start(root)
root.mainloop()
请随意批评我的结构
任何反馈将不胜感激!
Luke
Any feedback would be much appreciated! Luke
推荐答案
使用类的目的是将一堆行为封装为一个单元。对象不应修改自身以外的任何内容。至少不是简单地创建对象,而是可以有可能产生副作用的方法。
The point of using classes is to encapsulate a bunch of behavior as a single unit. An object shouldn't modify anything outside of itself. At least, not by simply creating the object -- you can have methods that can have side effects.
在我看来,创建页面的正确方法是:从 Frame
继承。属于页面的所有小部件都必须具有对象本身作为其父对象。例如:
In my opinion, the proper way to create "pages" is to inherit from Frame
. All of the widgets that belong to the "page" must have the object itself as its parent. For example:
class PageOne(tk.Frame):
def __init__(self, parent):
# use the __init__ of the superclass to create the actual frame
tk.Frame.__init__(self, parent)
# all other widgets use self (or some descendant of self)
# as their parent
self.label = tk.Label(self, ...)
self.button = tk.Button(self, ...)
...
完成后,您可以将此类的实例视为单个小部件:
Once done, you can treat instances of this class as if they were a single widget:
root = tk.Tk()
page1 = PageOne(root)
page1.pack(fill="both", expand=True)
您也可以创建基础 Page
类,并且如果您的所有页面都有一些共同点(例如,页眉或页脚),则让您的实际页面继承该类
You can also create a base Page
class, and have your actual pages inherit from it, if all of your pages have something in common (for example, a header or footer)
class Page(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
<code common to all pages goes here>
class PageOne(Page):
def __init__(self, parent):
# initialize the parent class
Page.__init__(self, parent)
<code unique to page one goes here>
这篇关于Tkinter类结构(每帧类)与小部件复制有关的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!