如果我说得对,我认为您的意思是拥有某种 基类,该类具有某些配置,一组框架具有共同点,例如您希望拥有 10 个框架300x400 几何形状和 棕色 背景共同,后来有另一组 具有不同配置的框架,可以以有组织的方式访问大大地。那我会说你有一个有趣的方式,但无论如何我宁愿使用列表或字典。
这里有一些实现这一目标的方法。
方法一
在这种方法中,我创建了一个函数,该函数返回一个字典,其中包含创建并包含在其中的所有帧,格式为 ({..., 'F20': tkinter.frame, ...})
import tkinter as tk
def get_base_frames(num, master, cnf={}, **kw):
"""
Create list of frames with common configuration options.
Args:
num (int): Number of frames to be created.
master (tk.Misc): Takes tkinter widget or window as a parent for the frames.
cnf (dict): configuration options for all the frames.
kw: configuration options for all the frames.
Return:
Dictionary of frames ({..., 'F20': tkinter.frame, ...}).
"""
return {f'F{n+1}': tk.Frame(master, cnf=cnf, **kw) for n in range(num)}
if __name__ == "__main__":
root = tk.Tk()
frame_holder = get_base_frames(10, root, width=50, height=50, bg='brown')
# Frames can be accessed through their names like so.
print(frame_holder.get('F1'))
方法2
这里我使用了类和对象。我在哪里开设了这门课Frames,尽管你可以随意命名。我还添加了一些重要的方法,如cget() 和configure(),通过这些方法一次获取一个选项的值并分别为所有框架配置选项。 还有更多有用的方法,如bind() 和bind_all(),如果您需要这些方法,只需根据需要修改此类即可。
import tkinter as tk
class Frames(object):
def __init__(self, master=None, cnf={}, **kw):
super().__init__()
num = cnf.pop('num', kw.pop('num', 0))
for n in range(num):
self.__setattr__(f'F{n+1}', tk.Frame(master, cnf=cnf, **kw))
def configure(self, cnf={}, **kw):
"""Configure resources of a widget.
The values for resources are specified as keyword
arguments. To get an overview about
the allowed keyword arguments call the method keys.
"""
for frame in self.__dict__:
frame = self.__getattribute__(frame)
if isinstance(frame, tk.Frame):
if not cnf and not kw:
return frame.configure()
frame.configure(cnf=cnf, **kw)
config = configure
def cget(self, key):
"""Return the resource value for a KEY given as string."""
for frame in self.__dict__:
frame = self.__getattribute__(frame)
if isinstance(frame, tk.Frame):
return frame.cget(key)
__getitem__ = cget
if __name__ == "__main__":
root = tk.Tk()
frame_holder = Frames(root, num=10, width=10,
bd=2, relief='sunken', bg='yellow')
# Frames can be accessed through their naems like so.
print(frame_holder.F4)
print(frame_holder['bg'])
frame_holder.config(bg='blue')
print(frame_holder['bg'])
方法 3
如果您希望在一个类中包含不同配置的框架,所有这些框架都有一些共同的方法或一些共同的属性。
import tkinter as tk
class BaseFrame(tk.Frame):
def __init__(self, master=None, cnf={}, **kw):
super().__init__(master=master, cnf={}, **kw)
def common_function(self):
"""This function will be common in every
frame created through this class."""
# Do something...
class FrameHolder(object):
def __init__(self, master=None, cnf={}, **kw):
kw = tk._cnfmerge((cnf, kw))
num = kw.pop('num', len(kw))
for n in range(num):
name = f'F{n+1}'
cnf = kw.get(name)
self.__setattr__(name, BaseFrame(master, cnf))
if __name__ == "__main__":
root = tk.Tk()
holder = FrameHolder(root,
F1=dict(width=30, height=40, bg='black'),
F2=dict(width=50, height=10, bg='green'),
F3=dict(width=300, height=350, bg='blue'),
F4=dict(width=100, height=100, bg='yellow'),
)
print(holder.F1)
print(holder.__dict__)
方法 4
这是 OP 试图实现的方法。
import tkinter as tk
class BaseClass(tk.Frame):
def __init__(self, master, cnf={}, **kw):
kw = tk._cnfmerge((cnf, kw))
cnf = [(i, kw.pop(i, None))
for i in ('pack', 'grid', 'place') if i in kw]
tk.Frame.__init__(self, master, **kw)
self.master = master
if cnf:
self.__getattribute__(cnf[-1][0])(cnf=cnf[-1][1])
class Container(tk.Frame):
"""Container class which can contain tkinter widgets.
Geometry (pack, grid, place) configuration of widgets
can also be passed as an argument.
For Example:-
>>> Container(root, widget=tk.Button,
B5=dict(width=30, height=40, bg='black',
fg='white', pack=(), text='Button1'),
B6=dict(width=50, height=10, bg='green', text='Button2',
place=dict(relx=0.5, rely=1, anchor='s')))
"""
BaseClass = BaseClass
def __init__(self, master=None, cnf={}, **kw):
kw = tk._cnfmerge((cnf, kw))
wid = kw.pop('widget', tk.Frame)
for name, cnf in kw.items():
geo = [(i, cnf.pop(i, None))
for i in ('pack', 'grid', 'place') if i in cnf]
setattr(Container, name, wid(master, cnf))
if geo:
manager, cnf2 = geo[-1]
widget = getattr(Container, name)
getattr(widget, manager)(cnf=cnf2)
if __name__ == "__main__":
root = tk.Tk()
Container(root, widget=Container.BaseClass,
F1=dict(width=30, height=40, bg='black', relief='sunken',
pack=dict(ipadx=10, ipady=10, fill='both'), bd=5),
F2=dict(width=50, height=10, bg='green',
pack=dict(ipadx=10, ipady=10, fill='both')),
)
Container(root, widget=tk.Button,
B5=dict(width=30, height=40, bg='black',
fg='white', pack={}, text='Button1'),
B6=dict(width=50, height=10, bg='green', text='Button2',
place=dict(relx=0.5, rely=1, anchor='s')),
)
print(Container.__dict__)
root.mainloop()
可以做很多事情,并且可以根据自己的需要进行修改,这些只是我认为可以很好地自动化并保持一组框架形状和在一起的一些方法。
有多种方法可以做到这一点,或者比这些更好、更有效的方法,请随时提出建议并分享新的东西。