添加行 - 网格Tkinter。 OptionMenu的各个命令

时间:2012-07-10 06:34:47

标签: python class lambda tkinter ttk

我在Tkinter中创建了一个表,在输入文本文件后重复小部件(因此根据包含的信息创建新的行)。

下图显示我需要能够从列'7'开始创建一个单独的输入框区域,具体取决于OptionMenu的选择。

Table

对于选项列表,系统会询问用户他们希望填写多少个输入框(因此创建了'n'框)。对于“固定”值,删除之前不应该有任何框和任何框。对于OptionMenu中的其他两个选项,始终存在最小值和最大值(2个框)。这些框中的每个值都需要在用户输入后收集。

我以前曾经有过每次创建新框架的可能性的帮助,但如果可能的话,我想使用相同的框架。我有以下代码供您选择:

if choice == "Fixed":

    for i in xrange(self.number_boxes):

        self.box[i].grid_remove()
        self.choice_title.grid_remove()
        self.frame_table.grid_columnconfigure(7, weight=0)
    tkMessageBox.showinfo("Message", "Value fixed.")
elif choice == "List":
    self.win2 = tk.Toplevel(self.root)
    self.win2.title("List")
    self.list_text = Label(self.win2, text="Please enter number of values to be used:")
    self.list_text.grid(row=0, column=0, sticky="nsew", padx=1, pady=1)
    self.value = StringVar()
    self.list_values = Entry(self.win2, textvariable=self.value, justify="center")
    self.list_values.grid(row=1, column=1, sticky="nsew", padx=1, pady=1)

    list_button = ttk.Button(self.win2, text="Enter", command=self.ValueBox)
    list_button.grid(row=2, column=1, sticky="nsew", padx=1, pady=1)
    self.win2.mainloop()

    column = 7
    self.number_boxes = int(self.number_boxes)
    self.numbers = [StringVar() for i in xrange(self.number_boxes) ]  
    self.box = []

    for i in xrange(self.number_boxes):
        self.clicked.append(False)
        self.choice_title = Label(self.frame_table, bg=self.mycolour, borderwidth=0, width=10) 
        self.choice_title.grid(row=1, column=self.column, columnspan=self.number_boxes, sticky="nsew", padx=1, pady=1) 
        self.box.append(Entry(self.frame_table,bg='white',borderwidth=0, width=10, justify="center", textvariable=self.numbers[i], fg='grey'))
        self.box[i].grid(row=self.row_list,column=self.column+i, sticky='nsew', padx=1, pady=1) 
        self.box[i].insert(0, "Value %g" % float(i+1))
        self.box[i].bind("<Button-1>", lambda event : self.callback(event))

        self.total_boxes = self.number_boxes * ( rows - 2 )
        self.boxes=[]
        self.boxes.append(self.box[i])

        tkMessageBox.showinfo("Message", "Please fill in list values.")

    for i in self.numbers: 
        i.trace('w',lambda : self.numberwritten() ) 

    elif choice == "Min" or "Max":

        self.numbers = [StringVar() for i in xrange(2) ] #Name available in global scope. 
        self.number_boxes = 2
        self.box = []
        for i in xrange(2): 
            self.clicked.append(False)
            self.choice_title = Label(self.frame_table, bg=self.mycolour, borderwidth=0)
            self.choice_title.grid(row=1, column=self.column, columnspan=2, sticky="nsew", padx=1, pady=1)
            self.box.append(Entry(self.frame_table,bg='white',borderwidth=0,textvariable=self.numbers[i], justify='center', fg='grey'))
            self.box[i].grid(row=self.row_list, column=self.column+i, sticky='nsew', padx=1, pady=1) 
        if i == 0:
            self.box[0].insert(0, "Min value")
        elif i == 1:
            self.box[1].insert(0, "Max value")
            self.box[i].bind("<Button-1>", lambda event : self.callback(event))
            self.boxes=[]
            self.boxes.append(self.box[i])

        tkMessageBox.showinfo("Message", "Enter Min/Max values.")

        for i in self.numbers: 
            i.trace('w',lambda a,b,n=i: self.numberwritten(n) ) 

更新部分

def numberwritten(self): # where the above code block is usually all indented differently in comparision to this.
    self.numbers.get()

def callback(self, event, index):

    if (self.clicked[index] == False):
        self.box[index].delete(0, END)
        self.box[index].config(fg='black')
        self.clicked[index] = True

我不想用代码轰炸这个问题,但如果需要任何其他功能,如数字编写,我可以提供它们。我非常感谢一些帮助,因为我即将结束,但我正在努力应对“最后的接触”。

1 个答案:

答案 0 :(得分:0)

以下循环中有一些可疑的东西(我会在鱼腥点添加评论)。

for i in xrange(self.number_boxes):
    self.clicked.append(False)
    self.choice_title = Label(self.frame_table, bg=self.mycolour, borderwidth=0, width=10)  #Fishy
    self.choice_title.grid(row=1, column=self.column, columnspan=self.number_boxes, sticky="nsew", padx=1, pady=1) 
    self.box.append(Entry(self.frame_table,bg='white',borderwidth=0, width=10, justify="center", textvariable=self.numbers[i], fg='grey'))
    self.box[i].grid(row=self.row_list,column=self.column+i, sticky='nsew', padx=1, pady=1) 
    self.box[i].insert(0, "Value %g" % float(i+1))
    self.box[i].bind("<Button-1>", lambda event, index=i : self.callback(event, index))

    self.total_boxes = self.number_boxes * ( rows - 2 ) #fishy
    self.boxes=[] #fishy
    self.boxes.append(self.box[i])

    tkMessageBox.showinfo("Message", "Please fill in list values.") #fishy

首先,您要创建choice_title标签,但是您只保留对您正在创建的标签之一的引用。也许你应该把它改成一个列表,并像对待列表一样附加到它上面。

其次,每次循环都不需要计算self.total_boxes。它可以在最后计算(我认为)。

第三,self.boxes=[]应该在循环之前移动。你所做的相当于:self.boxes=[self.box[i]]在循环的每一步。完成后,您的方框列表中只有一个方框(最后一个方框)。

第四,在循环的每次迭代中都会向用户提示一个消息框。这真的是你想要的吗?或者是缩进错误?

这里可能有更多的东西有点奇怪,但这些给你一个开始的地方。以下是我认为它的外观:

self.box=[]
self.boxes=[]
self.choice_title=[]
for i in xrange(self.number_boxes):
    self.clicked.append(False)
    choice_title = Label(self.frame_table, bg=self.mycolour, borderwidth=0, width=10)  #Fishy
    choice_title.grid(row=1, column=self.column, columnspan=self.number_boxes, sticky="nsew", padx=1, pady=1)
    self.choice_title.append(choice_title)
    box=Entry(self.frame_table,bg='white',borderwidth=0, width=10, justify="center", textvariable=self.numbers[i], fg='grey')
    self.box.append(box)
    box.grid(row=self.row_list,column=self.column+i, sticky='nsew', padx=1, pady=1) 
    box.insert(0, "Value %g" % float(i+1))
    box.bind("<Button-1>", lambda event, index=i : self.callback(event, index))

    self.boxes.append(box)  #This is still a little weird since self.box and self.boxes are essentially the same information.

self.total_boxes = self.number_boxes * ( rows - 2 ) #fishy
tkMessageBox.showinfo("Message", "Please fill in list values.")