虽然我认为解决方案可能类似于这个问题:tkinter, display a value from subwindow in mainwindow,我仍然决定提出这个问题,因为我很难自己解决这个问题。
我有列表"字段"我正在创建任何给定数量的行,其中有两个实验室。在打开一个子窗口后,我希望能够操作该列表(在我的示例中只是简单地追加)并且在单击按钮(此处" ADD")之后,我希望主窗口更新,这样它就显示了被操纵列表的行。它在大多数情况下工作正常,但我不知道在这个例子中更新主窗口的最佳方法是什么。
我能想出的唯一解决方案是破坏主窗口并重新创建它,但我觉得这可能不是最好的解决方案。还有更好的吗?
import tkinter as tk
a=0
fields=[("a",1),("c",2),("e",3)]
class clsApp(object):
def __init__(self):
self.root=tk.Tk()
self.root.title("MainWindow")
##Labels##
self.rootLabel=tk.Label(self.root, text="WindowAppExperiment", padx=100)
self.aLabel=tk.Label(self.root, text=a, padx=100)
##Buttons##
self.BtExit=tk.Button(self.root, text="Quit", fg="red", command=self.root.quit)
###self.BtNewWindow=tk.Button(self.root, text ="Edit", command=lambda:self.clsNewWindow(self.root, self.aLabel).run())
self.BtNewField=tk.Button(self.root, text ="New Field", padx=30, command=lambda:self.clsNewFields(self.root).run())
def grid (self):
self.rootLabel.pack()
self.aLabel.pack()
self.fckPackFields()
self.BtNewField.pack()
self.BtExit.pack(side="left")
###self.BtNewWindow.pack(side="right")
def fckPackFields(self):
if fields:
for field in fields:
##create labels##
row=tk.Frame(self.root)
nameLabel=tk.Label(row, text =field[0], width=20, anchor="w")
valueLabel=tk.Label(row, text =field[1], width=5)
##pack labels##
row.pack(side="top", fill="x", padx=5, pady=5)
nameLabel.pack(side="left")
valueLabel.pack(side="right", expand=True, fill="x")
def run(self):
self.grid()
self.root.mainloop()
self.root.destroy()
class clsNewFields(object):
def __init__(self, Parent):
self.parent=Parent
##Window##
self.top=tk.Toplevel()
self.top.title("Add Fields")
##Labels##
self.enterNameLabel=tk.Label(self.top, text ="Enter fieldname", padx=10)
self.enterValueLabel=tk.Label(self.top, text ="Enter value", padx=10)
##Entryfields##
self.EntryName=tk.Entry(self.top)
self.EntryValue=tk.Entry(self.top)
##Buttons##
self.BtADD=tk.Button(self.top, text ="ADD", command=lambda:self.fckAddField(self.EntryName, self.EntryValue))
self.BtClose=tk.Button(self.top, text ="Close", command=self.top. quit)
def grid(self):
self.enterNameLabel.pack()
self.enterValueLabel.pack()
self.EntryName.pack()
self.EntryValue.pack()
self.BtADD.pack()
self.BtClose.pack()
def fckAddField(self, Name, Value):
self.name=Name.get()
self.value=Value.get()
global fields
fields.append((self.name, self.value))
print(fields)
self.parent.update
def run(self):
self.grid()
self.top.mainloop()
self.top.destroy()
clsApp().run()
答案 0 :(得分:0)
欢迎使用StackOverflow。
首先 - 你真的想宣布你的clsNewFields
内的clsApp
吗?是的,应该在App中使用Fields,但我认为不需要使用 class-in-class-declaration 。
第二 - 您正在def fckPackFields(self):
中打包字段。更新时不会自动调用它。
您未使用update
调用self.parent.update
功能。
您正在使用字段的全局变量,这不适合您的需求。为什么不在App类中列出如下列表:
def __init__(self):
self.__fields=[]
def __set_fields(self, value):
self.__fields=value
def __get_fields(self):
return self.__fields
Fields = property(__get_fields, __set_fields)
def __loadUI(self, event=None):
# This function should be called at the end of __init__
self.fieldFrame=tk.Frame(self.root)
self.fieldFrame.pack(side="top")
def fckPackFields(self):
#First clean area
[...]
#Then add fields
for field in self.__fields:
# create the row, etc.
# !!! but do it inside self.fieldFrame !!!
[...]
我更喜欢在这里使用网格而不是打包,因为在那里我认为将框架放置在某个位置更容易,然后你可以销毁self.fieldFrame
并在同一位置重新创建它以放置其中的字段。
<强>更新强>
再次检查您的代码。通过一些简单的技巧,您可以调整GUI以执行您想要的操作:
def __init__(self):
self.fieldFrame=None #this line has been added
#completely reworked this function
def grid(self):
self.rootLabel.grid(row=1, column=0, columnspan=2, sticky=tk.NW+tk.SE)
self.fckPackFields()
self.BtNewField.grid(row=3, column=0, sticky=tk.NW+tk.SE)
self.BtExit.grid(row=3, column=1, sticky=tk.NW+tk.SE)
#Only one line changed / one added
def fckPackFields(self):
self.__cleanFields() #added this line, function beyond
if fields:
for field in fields:
##create labels##
row=tk.Frame(self.fieldFrame) #add the row to the fieldFrame
[...]
#In here we destroy and recreate fieldFrame as needed
def __cleanFields(self):
if self.fieldFrame:
self.fieldFrame.destroy()
##FieldFrame##
self.fieldFrame=tk.Frame(self.root)
self.fieldFrame.grid(row=2, column=0, columnspan=2)
在clsNewFields
:
def fckAddField(self, Name, Value):
[...]
self.parent.fckPackFields() # instead of self.parent.update
修改强>
看看这两个问题:
我并不是要指出一般要避免使用嵌套类,但我确实希望将您的注意力集中在的思想上“对于我的用例来说,它是否真的有必要或有益”< / em>的