Tkinter 添加标签框架

1 投票
2 回答
3585 浏览
提问于 2025-04-18 17:40

我一直在尝试,但没有成功。
我有一个标签框,里面有一些输入框。我想添加一个按钮,这样用户就可以在工具中添加多个框,框里也有输入框和按钮,放在现有标签框的下面。而当添加新的框时,下面的文本框应该会移动。以下是我用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 来记录文本小部件上方有多少行网格。

撰写回答