条目小部件Tkinter中的回调问题

时间:2012-06-26 14:21:49

标签: python tkinter tkinter-entry

我有以下代码(仅限部分)用于获取我创建的4个条目框中的条目。但是我有两个小问题:

  • 当我输入每个框时,它会输入相同的内容,我希望输入不同的数字,并将所有数字分配给不同的变量。

  • 有没有办法在一个循环中产生4个盒子并且比这个更少的行?

    number = StringVar() def numberwritten(* args):     number.trace(“w”,数字)     fg = number.get()     print fg

    在单独的定义中定义ChoiceBox(选择):(不在此def下的完整代码)

    def ChoiceBox(选择):         i = [0,1,2,3]

        for i in i:
            choice_title = Label(choice_frame, text='Value %g'% float(i+1), bg='white', borderwidth=0, width=0)
            choice_title.grid(row=0, column=column+i, sticky="nsew", padx=1, pady=1)
    
        box1 = Entry(choice_frame, bg='white', borderwidth=0, width=0, textvariable=number)
        box1.grid(row=1, column=0, sticky="ew", padx=1, pady=1)
        box2 = Entry(choice_frame, bg='white', borderwidth=0, width=0, textvariable=number)
        box2.grid(row=1, column=1, sticky="ew", padx=1, pady=1)
        box3 = Entry(choice_frame, bg='white', borderwidth=0, width=0, textvariable=number)
        box3.grid(row=1, column=2, sticky="ew", padx=1, pady=1)
        box4 = Entry(choice_frame, bg='white', borderwidth=0, width=0, textvariable=number)
        box4.grid(row=1, column=3, sticky="ew", padx=1, pady=1)
    

UPDATE /编辑:

这是我所拥有的代码部分,并且由于我收到语法错误而无法弄清楚它最终出了什么问题:

def numberwritten(number):
    fg = number.get()
    print fg

numbers = [StringVar() for i in xrange(4) ] #Name available in global scope. 
for i in numbers: 
    i.trace('w',lambda n=i: numberwritten(n) ) 


def ChoiceBox(choice):


    column = 0
    if choice == "Fixed":
        choice_frame.grid_forget()      
    tkMessageBox.showinfo("Message", "No optimisation, value fixed.")
    elif choice == "List":

        for i in xrange(4): 
            choice_title = Label(choice_frame, text='Value %g'% float(i+1), bg='white', borderwidth=0, width=0) 
        choice_title.grid(row=0, column=column+i, sticky="nsew", padx=1, pady=1) 
        boxes=[] 

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


    elif choice == "Interval" or "Optimisation":
        i = [0, 1]
        choice_title1 = Label(choice_frame, text='Min Value', bg='white', borderwidth=0, width=0)
        choice_title1.grid(row=0, column=column, sticky="N S E W", padx=1, pady=1)
        choice_title2 = Label(choice_frame, text='Max Value', bg='white', borderwidth=0, width=0)
        choice_title2.grid(row=0, column=column+1, sticky="nsew", padx=1, pady=1)

        boxes=[]

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

for i in xrange(4): 
        box=Entry(choice_frame,bg='white',borderwidth=0,textvariable=numbers[i]) 
        box.grid(row=1,column=i, sticky='ew', padx=1, pady=1 
        boxes.append(box)
    box1,box2,box3,box4=boxes

2 个答案:

答案 0 :(得分:1)

StringVarEntry的模型(以及Tkinter中的其他一些内容)。您已经为每个Entry实例提供了对同一StringVar对象的引用,因此它们自然会共享模型,从而显示相同的内容。您需要制作四个不同的StringVar个对象,每个Entry一个。 (那些,你将在循环中创建迭代StringVar s的集合......)

答案 1 :(得分:0)

首先,请停止使用:

i=[1,2,3,4]
for i in i:
    ...

使用:

for i in (1,2,3,4):
    ...

代替。

或更好:

for i in xrange(1,5): #range in python3.x
    ...

现在,在循环中创建东西很简单:

strvars=[]
boxes=[]
for i in xrange(1,5):
    svar=StringVar()
    box=Entry(choice_frame, bg='white', borderwidth=0, width=0, textvariable=svar)
    box.grid(row=1, column=i-1, sticky="ew", padx=1, pady=1)
    svar.trace('w',numberwritten)
    #If you want to pass the box associated with the stringvar, you can do this:
    #svar.trace('w',lambda a,b,c,box=box : numberwritten(box)) #box.get() get's the contents of an Entry too!
    strvars.append(svar)
    boxes.append(box)

number1,number2,number3,number4=strvars  #unpack stringvars 
box1,box2,box3,box4=boxes   #unpack boxes

每个框都需要一个不同的StringVar。仅当您知道包含StringVars和Entry框的列表中有多少项时,解包才有效。否则,您可以通过boxes[0]strvars[0]获取所需的框/变量的引用。

修改

这样的事情应该有用......

def numberwritten(number):
    fg = number.get()
    print fg 

numbers = [StringVar() for i in xrange(4) ]  #Name available in global scope.
for i in numbers:
    i.trace('w',lambda a,b,c,n=i: numberwritten(n) )

# In separate definition def ChoiceBox(choice): (not full code under this def)
def ChoiceBox(choice):  

    for i in xrange(4):
        choice_title = Label(choice_frame, text='Value %g'% float(i+1), bg='white', borderwidth=0, width=0)
        choice_title.grid(row=0, column=column+i, sticky="nsew", padx=1, pady=1)

    boxes=[]
    for i in xrange(4):
        box=Entry(choice_frame,bg='white',borderwidth=0,textvariable=numbers[i])
        box.grid(row=1,column=i, sticky='ew', padx=1, pady=1
        boxes.append(box)

    box1,box2,box3,box4=boxes

顺便说一句,为什么你到处都在使用width=0?没有宽度的条目/标签几乎没用。