Question

In the code below I need to return all values returned (but for each row separately) but I have tried lambda and failed and I'm not getting anywhere AGAIN.

I also have the callback definition where it previously worked and when I click in a box, it deletes the grey writing so I can continue to input in black.

If possible I would like to add the value return for the entry box at the end of my callback function rather than keeping 'numberwritten' and 'callback'..Is this possible?

The number of boxes added is equal to self.number_boxes and can be from 1 to n.

Thank you.

UPDATED CODE:

    self.numbers = [StringVar() for i in xrange(self.number_boxes) ] 

    for i in xrange(self.number_boxes):
          row = (row_number +add)
          column = self.column +i
          key = "%d/%d" % (row,column)
          self.clicked = ([False] * self.number_boxes)
          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.choice_titles.append(self.choice_title)
          self.box[key] = Entry(self.frame_table,bg='white',borderwidth=0, width=10, justify="center", fg='grey')
          self.box[key].grid(row=row_number+add,column=self.column+i, sticky='nsew', padx=1, pady=1) 
          self.box[key].insert(0, "Value %g" % float(i+1))
          self.box[key].bind("<Button-1>", lambda event, key=key, index=i : self.callback(event, key, index))
          self.boxes.append(self.box[key])


def callback(self, event, key, index):

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

         print self.box[key].get()
Was it helpful?

Solution

You have at least a couple of choices. For one, you can store store the entry widgets in a dict or list of lists, then pass the index into the callback. For example:

self.box = {}
for i in xrange(self.number_boxes):
    row = row_number+add
    column = self.column+i
    key = "%d/%d" % (row,column)
    ...
    self.box[key] = Entry(...)
    self.box[key].bind("<Button-1>", lambda event, key=key: self.callback(event, key))

The important thing is to not just pick a method somebody gives you on the internet, but to understand the problem and the tools you have to solve it. If you take the time to learn how lambda works (or functools.partial) and have a basic understanding of fundamental data structures like lists and dicts, problems like this will cease to be stumbling blocks.

OTHER TIPS

For python newbies (like me) who are confused by this line

self.numbers = [StringVar() for i in xrange(self.number_boxes) ] 

The keyword to google is 'list comprehension', this is a way to initialize a list in the format

[ expression for-clause ]

which is equivalent to the snippet

self.numbers = []
for i in xrange(self.number_boxes)
    self.numbers.append(StringVar())

In other words it creates a list initialized as

[ StringVar, StringVar, StringVar, StringVar, ... ]

whose values are set later.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top