0
我想在Tkinter GUI中创建一堆子帧,每个子帧都包含一些用户输入变量,我需要稍后才能通过唯一每个子帧的ID。我需要能够添加和删除随意子帧,并让他们在一个合理的顺序ID'd(整数从1计数,此刻)添加和删除tkinter帧 - 跟踪实例
三个问题真的:
1)具体来说,为什么标签小部件显示每个框架的标题不显示? (这可能是愚蠢的......)
2)具体来说,为什么有时需要两次按下添加或删除按钮来添加或删除一个框架?
3)通常:有更好的方法来解决这个问题吗?在追踪帧实例的意义上。他们现在在列表中...我早些时候开始使用字典,但与...合作更难...有更好的建议吗?
from tkinter import *
from tkinter.ttk import *
class AllInstances(Tk):
def __init__(self):
Tk.__init__(self)
self.master_frame = Frame(self)
self.master_frame.grid()
self.all_instances = []
root = AllInstances()
class OneInstance():
def __init__(self):
self.number = len(root.all_instances) + 1
var1 = StringVar()
var2 = StringVar()
var3 = StringVar()
self.sub_frame = Frame(root.master_frame)
self.sub_frame.grid(column = self.number, row = 0)
titletext = StringVar()
titletext.set('%s %s' % ('Frame', self.number))
print(titletext.get())
title = Label(self.sub_frame, textvariable = titletext)
title.grid() #work out why this label does not display!
uservar1 = Entry(self.sub_frame, textvariable = var1)
uservar1.grid()
uservar2 = Entry(self.sub_frame, textvariable = var2)
uservar2.grid()
uservar3 = Entry(self.sub_frame, textvariable = var3)
uservar3.grid()
#etc etc
add_button = Button(self.sub_frame, text = 'Add', command = lambda: Create())
add_button.grid()
def RemoveInstance(self):
if len(root.all_instances) > 1:
root.all_instances.remove(self)
self.sub_frame.destroy()
for instance in root.all_instances:
instance.number = (root.all_instances.index(instance) + 1)
else:
pass
remove_button = Button(self.sub_frame, text = 'Remove', command = lambda: RemoveInstance(self))
remove_button.grid()
root.all_instances.append(self)
def Create():
OneInstance()
Create()
root.mainloop()
谢谢... :)
谢谢布莱恩。我想我可以看到你如何重组它的逻辑。你更简单的.pack()方法避免了获得正确列的问题,但连续的列和框架名称对我来说是必需的,所以我必须再次使用.grid()来查看。 Re:导入ttk并覆盖tkinter - 我很满意,并且不需要tk.widget或ttk.widget的清晰度(基于我实际使用的所有小部件都被覆盖,然后我可以不使用ttk样式额外的打字),但是我还有其他缺点吗? – Tom
@Tom:包和网格与框架名称无关。至于其他缺点,我只是说,不做全球进口是最好的做法。另外,当您执行全局导入时,它会使代码更难理解。例如,我认为你使用的是tkinter按钮和标签,直到我弄清楚我的回答后才意识到你是依赖tkk进口来覆盖tk进口。如果你使用'ttk.Button'或者'tk.Button',你的代码很清楚你正在使用哪个小部件,并且在编写软件时清晰度应该是一个高优先级的目标。 –
@Tom:如果你想要连续的列名,即使用户在中间删除了一列,一个简单的解决方案是给Subframe类添加一个'rename'方法,然后让'Remove'函数迭代所有这些实例使用每列所需的新名称进行重命名。 –