Reputation: 1005
I have the following code (only sections of it) for getting the entries in 4 Entry boxes I have created. However I have two niggles:
When I type into each box, it types the same thing and I wish to type different numbers and assign all of them to separate variables.
Is there any way of producing 4 boxes in a loop and fewer lines than this?
number = StringVar() def numberwritten(*args): number.trace("w", numberwritten) fg = number.get() print fg
def ChoiceBox(choice): 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/EDIT:
This is the section of code I have and cannot figure out what's going wrong with it at the end as I'm receiving syntax errors:
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
Upvotes: 0
Views: 466
Reputation: 310297
First, please stop using:
i=[1,2,3,4]
for i in i:
...
Use:
for i in (1,2,3,4):
...
instead.
Or better:
for i in xrange(1,5): #range in python3.x
...
Now, creating the stuff in the loop is easy:
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
You need a distinct StringVar
for each box. The unpacking only works if you know how many items there are in the lists holding the StringVars and Entry boxes. Otherwise, you can get references to the box/variable you want by boxes[0]
and strvars[0]
for example.
EDIT
Something like this should work...
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
As an aside, why are you using width=0
everywhere? an Entry/Label with no width is pretty much useless.
Upvotes: 0
Reputation: 137797
The StringVar
is a Model for the Entry
(and a few other things in Tkinter). You've given each Entry
instance a reference to the same StringVar
object, so naturally they share the model and thus show the same contents. You'll need to make four different StringVar
objects, one for each Entry
. (Those, you'll create in a loop that is iterating over the collection of StringVar
s…)
Upvotes: 1