我正在编写一个tkinter程序,该程序将具有多种模式,并希望更改窗口各个部分的帧以响应模式更改。
以下代码旨在创建一个可以在包含的帧之间切换的抽象SwitcherClass。 SwitchedFrame派生自SwitcherClass,并且有一个class属性,列出了应该切换的帧(在本例中为Myclass和Myotherclass)。
它有两个意想不到的行为:
SwitcherClass中的词典self.children应该有两个条目,但最终会有四个条目。 SubClass对象最终在字典中作为键和值,因此每次运行循环都会创建两个字典条目!
SwitcherClass中的pack()和pack_forget()调用什么都不做。实际上,如果SwitcherClass的子节点从未打包过,它们仍会显示在主窗口中。为什么呢?
我非常感谢这些谜题中的一个或两个的答案。
import tkinter as tk
class Myclass(tk.Frame):
def __init__(self,parent):
super().__init__(parent)
tk.Button(text='Myclass',command=parent.switch).pack()
class Myotherclass(tk.Frame):
def __init__(self,parent):
super().__init__(parent)
tk.Button(text='Myotherclass',command=parent.switch).pack()
class SwitcherClass(tk.Frame):
def __init__(self,parent):
super().__init__(parent)
self.children = {}
for label,Subclass in self.contains:
self.children[label] = Subclass(self)
print(self.children)
self.frame = 'first'
self.children[self.frame].pack()
def switch(self):
old_frame = self.frame
if self.frame == 'second':
self.frame = 'first'
else:
self.frame = 'second'
self.children[old_frame].pack_forget()
self.children[self.frame].pack()
class SwitchedFrame(SwitcherClass):
contains = (('first',Myclass),('second',Myotherclass))
root = tk.Tk()
tk.Label(root,text='root frame').pack()
SwitchedFrame(root).pack()
root.mainloop()
答案 0 :(得分:1)
首先: tkinter
中的每个小部件都使用self.children
来保留自己的孩子,因此请为您使用不同的名称 - 即。 self.my_children
。现在,您会看到tkinter
自动添加自己的小部件和小部件。
第二个:没有父级的窗口小部件已分配给root
,因此您的按钮也会分配给root
,您可以在主窗口中看到它们,而不是在子框架中看到它们(但他们改变没有按钮的框架没有尺寸)。
您必须使用Button(self, ...)
指定按钮才能更正框架。
import tkinter as tk
class Myclass(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
tk.Button(self, text='Myclass',command=parent.switch).pack()
class Myotherclass(tk.Frame):
def __init__(self,parent):
super().__init__(parent)
tk.Button(self, text='Myotherclass',command=parent.switch).pack()
class SwitcherClass(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.my_children = {}
for label,Subclass in self.contains:
self.my_children[label] = Subclass(self)
for x in self.my_children:
print('child:', x)
self.frame = 'first'
self.my_children[self.frame].pack()
def switch(self):
old_frame = self.frame
if self.frame == 'second':
self.frame = 'first'
else:
self.frame = 'second'
self.my_children[old_frame].pack_forget()
self.my_children[self.frame].pack()
class SwitchedFrame(SwitcherClass):
contains = (('first',Myclass), ('second',Myotherclass))
root = tk.Tk()
tk.Label(root,text='root frame').pack()
SwitchedFrame(root).pack()
root.mainloop()