Tkinter 添加标签框架
我一直在尝试,但没有成功。
我有一个标签框,里面有一些输入框。我想添加一个按钮,这样用户就可以在工具中添加多个框,框里也有输入框和按钮,放在现有标签框的下面。而当添加新的框时,下面的文本框应该会移动。以下是我用tkinter写的代码:
from Tkinter import *
root=Tk()
root.title("CIME")
step = LabelFrame(root,text="Enter Details:")
step.grid(row=0, columnspan=7, sticky='W',padx=5, pady=5, ipadx=5, ipady=5)
Label(step,text="Competitors",font = "Arial 8 bold italic").grid(row=0,sticky='E', padx=5, pady=2)
Label(step,text="Keywords",font = "Arial 8 bold italic").grid(row=1,sticky='E', padx=5, pady=2)
Label(step,text="Project Name",font = "Arial 8 bold italic").grid(row=2,sticky='E', padx=5, pady=2)
e1 = Entry(step)
e2=Entry(step)
e3=Entry(step)
e1.grid(row=0,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
e2.grid(row=1,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
e3.grid(row=2,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
tex = Text(master=root)
scr=Scrollbar(root,orient =VERTICAL,command=tex.yview)
scr.grid(padx=1, column=7, rowspan=15, columnspan=1, sticky=NS)
tex.grid(row = 4,column=1)
tex.config(yscrollcommand=scr.set,font=('Arial', 8, 'bold', 'italic'))
#tex['yscrollcommand'] = sb.set
Button(step,text ="Search Words",width=10,font = "Arial 8 bold italic",activebackground="red",command=roll).grid(row=3,column=0,sticky=W,pady=4,padx=5)
Button(step,text="Google Search",width=10,font = "Arial 8 bold italic",command = links).grid(row=3,column=2,sticky=W,pady=4,padx=5)
Button(step,text="Extraxt Text",width=10,font = "Arial 8 bold italic",command = create).grid(row=3,column=4,sticky=W,pady=4,padx=5)
mainloop()
2 个回答
2
解决方案的第一步是创建一个函数,用来生成标签框和输入框。更好的做法是把这些代码放到一个类里面,这样你就可以把整个东西当作一个单独的组件来使用。这会让你的代码更容易理解,也更方便进行视觉布局。
比如说:
class CustomFrame(LabelFrame):
def __init__(self, parent, text):
LabelFrame.__init__(self, parent, text=text)
Label(self,text="Competitors",font = "Arial 8 bold italic").grid(row=0,sticky='E', padx=5, pady=2)
Label(self,text="Keywords",font = "Arial 8 bold italic").grid(row=1,sticky='E', padx=5, pady=2)
Label(self,text="Project Name",font = "Arial 8 bold italic").grid(row=2,sticky='E', padx=5, pady=2)
self.e1=Entry(self)
self.e2=Entry(self)
self.e3=Entry(self)
self.e1.grid(row=0,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
self.e2.grid(row=1,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
self.e3.grid(row=2,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
Button(self,text ="Search Words",width=10,font = "Arial 8 bold italic", activebackground="red",
command=roll).grid(row=3,column=0,sticky=W,pady=4,padx=5)
Button(self,text="Google Search",width=10,font = "Arial 8 bold italic",
command = links).grid(row=3,column=2,sticky=W,pady=4,padx=5)
Button(self,text="Extraxt Text",width=10,font = "Arial 8 bold italic",
command = create).grid(row=3,column=4,sticky=W,pady=4,padx=5)
def getValues(self):
"""Return a dictionary of values from the widget"""
return {"competitors": self.e1.get(),
"keywords": self.e2.get(),
"name": self.e3.get()
}
接下来,你可以用这个函数来创建你最初的一组组件。而且,因为你想添加新的标签框,使用 pack
来管理这些框会更好,这样你就不需要一直往网格中添加行了。所以,我建议你专门创建一个容器来放这些标签框。然后你可以用 pack
把它们一个叠一个地放在一起。
你的主程序看起来大概是这样的:
root = Tk()
root.title("CIME")
frames = Frame(root)
frames.grid(row=0, column=0, sticky="nsew")
tex = Text(master=root)
scr=Scrollbar(root,orient =VERTICAL,command=tex.yview)
scr.grid(row = 1, column=1, padx=1, sticky=NS)
tex.grid(row = 1, column=0)
tex.config(yscrollcommand=scr.set,font=('Arial', 8, 'bold', 'italic'))
step = CustomFrame(frames, "Enter Details:")
step.pack(side="top")
mainloop()
现在,每次你需要一个新的框时,只需创建一个新的实例。如果你保留对这个组件的引用,你可以使用 getValues
方法来返回一个字典,里面包含每个输入框的值。
现在你只需要一个非常简单的函数来创建一个新的 CustomFrame
实例,并用 pack
把它放到 frames
里面。它看起来大概是这样的:
def newFrame():
f = CustomFrame(frames, "Another Frame")
f.pack(side="top")
... 不过,你可能想把 f
加入到一个列表或字典中,这样你就可以在代码的后面某个地方获取这些值。
0
定义一个函数,用来生成一个带有 输入详细信息 标签的框架。然后在新按钮的回调函数中调用这个函数。
from Tkinter import *
def roll(): pass
def links(): pass
def create(): pass
root=Tk()
root.title("CIME")
rows = 0
def create_detail_frame():
global rows
step = LabelFrame(root,text="Enter Details:")
step.grid(row=rows, columnspan=7, sticky='W',padx=5, pady=5, ipadx=5, ipady=5)
Label(step,text="Competitors",font = "Arial 8 bold italic").grid(row=0,sticky='E', padx=5, pady=2)
Label(step,text="Keywords",font = "Arial 8 bold italic").grid(row=1,sticky='E', padx=5, pady=2)
Label(step,text="Project Name",font = "Arial 8 bold italic").grid(row=2,sticky='E', padx=5, pady=2)
e1 = Entry(step)
e2 = Entry(step)
e3 = Entry(step)
e1.grid(row=0,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
e2.grid(row=1,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
e3.grid(row=2,column=1,columnspan=7, sticky="WE", pady=3,padx=5)
Button(step,text ="Search Words",width=10,font = "Arial 8 bold italic",activebackground="red",command=roll).grid(row=3,column=0,sticky=W,pady=4,padx=5)
Button(step,text="Google Search",width=10,font = "Arial 8 bold italic",command=links).grid(row=3,column=2,sticky=W,pady=4,padx=5)
Button(step,text="Extraxt Text",width=10,font = "Arial 8 bold italic",command = create).grid(row=3,column=4,sticky=W,pady=4,padx=5)
rows += 1
# Reposition text, scroll
#scr.grid_forget()
#tex.grid_forget()
#scr.grid(row=rows, padx=1, column=7, rowspan=15, columnspan=1, sticky=NS)
#tex.grid(row=rows,column=1)
# Reposition text, scroll
scr.grid(row=rows)
tex.grid(row=rows)
tex = Text(master=root)
scr=Scrollbar(root,orient =VERTICAL,command=tex.yview)
scr.grid(row=1, padx=1, column=7, rowspan=15, columnspan=1, sticky=NS)
tex.grid(row=1,column=1)
tex.config(yscrollcommand=scr.set,font=('Arial', 8, 'bold', 'italic'))
Button(root, text='Add detail frame', command=create_detail_frame).grid(row=0, column=7)
create_detail_frame()
mainloop()
注意:我使用了一个全局变量 rows
来记录文本小部件上方有多少行网格。