我正在尝试在Tkinter GUI中创建一堆子帧,每个子帧包含一些用户输入变量,我需要通过每个子帧的唯一ID来获取这些变量。我需要能够随意添加和删除子帧,并以合理的顺序对它们进行ID识别(此时整数从1开始计算)
真的有三个问题:
1)具体来说,为什么Label小部件显示每个帧的标题不显示? (这可能是愚蠢的......)
2)具体来说,为什么有时两次按下添加或删除按钮来添加或删除一个框架?
3)一般来说:有没有更好的方法来解决这个问题?在跟踪框架实例的意义上。他们现在在列表中...我之前开始使用dict但是更难以使用...是否有更好的建议?
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()
谢谢...:)
答案 0 :(得分:0)
这就是我要做的事情:
AllInstances
继承自Frame
(并重命名为“FrameGroup”之类的东西)。然后它变成一个“megawidget”,子帧是可以直接控制的子节点。Frame
的子类(并将其称为“子帧”)。这也是一个“megawidget”,它需要与其父级松散耦合(即:它不应该知道root.all_instances
我还建议不进行全局导入。由于您同时使用ttk和tkinter,因此根据您订购import语句的顺序,将覆盖另一个。
这是一个包含这些修改的工作示例:
import tkinter as tk
class FrameGroup(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.all_instances = []
self.counter = 0
def Add(self):
self.counter += 1
name = "Frame %s" % self.counter
subframe = Subframe(self, name=name)
subframe.pack(side="left", fill="y")
self.all_instances.append(subframe)
def Remove(self, instance):
# don't allow the user to destroy the last item
if len(self.all_instances) > 1:
index = self.all_instances.index(instance)
subframe = self.all_instances.pop(index)
subframe.destroy()
def HowMany(self):
return len(self.all_instances)
def ShowMe(self):
for instance in self.all_instances:
print(instance.get())
class Subframe(tk.Frame):
def __init__(self, parent, name):
tk.Frame.__init__(self, parent)
self.parent = parent
self.e1 = tk.Entry(self)
self.e2 = tk.Entry(self)
self.e3 = tk.Entry(self)
label = tk.Label(self, text=name, anchor="center")
add_button = tk.Button(self, text="Add", command=self.parent.Add)
remove_button = tk.Button(self, text="Remove", command=lambda: self.parent.Remove(self))
label.pack(side="top", fill="x")
self.e1.pack(side="top", fill="x")
self.e2.pack(side="top", fill="x")
self.e3.pack(side="top", fill="x")
add_button.pack(side="top")
remove_button.pack(side="top")
def get(self):
return (self.e1.get(), self.e2.get(), self.e3.get())
class GUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.master_frame = tk.Frame(self)
self.master_frame.grid()
self.all_instances = FrameGroup(self.master_frame)
self.all_instances.grid()
# create the first frame
self.all_instances.Add()
root = GUI()
root.mainloop()