Search code examples
pythonloopsbuttontkintertkinter-entry

Creating entry and buttons linked in tkinter


I'm creating a GUI where I need to create certain number of entries and buttons in Tkinter. I'd like to create all these in a for loop. As actions, when I press any of the button, it should transfer the value of the Entry to the callback of the button next to it.

This is what I've done so far but it's not working yet.

 n=0
 self.button = []
 self.entFreq = []

 for calVal in calibration:                                                                             
    lbl = Label(self.calFrame)
    lbl.configure(text = "Set amplitud to " + calVal)
    lbl.configure(background=self.bg_App, fg = "white")
    lbl.grid(row=n, column=0)

    self.entFreq.append(Entry(self.calFrame, width=10))
    self.entFreq[n].grid(row=n, column=1, padx = 10)

    #Construction Button send frequency
    self.button.append(Button(self.calFrame, text="Cal", borderwidth=0, relief="groove", command = lambda n=self.entFreq[n].get(): self.get_val(n)))
    self.button[n].configure(bg="#FFF3E0")
    self.button[n].grid(row=n, column=2)
    n+=1

def get_val(self, var):
    print "Got this:", str(var)

I'm just getting blank in the var function. How to link those two?


Solution

  • You're putting too much code into your lambdas. You only need to pass in n, and get_val can do the rest of the work:

    self.button.append(Button(..., command=lambda n=n: self.get_val(n)))
    ...
    def get_val(self, n):
        value = self.entFreq[n].get()
        print "Got this:", value
    

    You might want to consider defining a class for this set of label, entry and button, since they are designed to work together and you're making several sets.

    You could, for example,pass in a label and a function to call when the user clicks the button. For example:

    class LabelEntry(object):
        def __init__(self, parent, text, command):
            self.command = command
            self.label = Label(parent, text=text)
            self.entry = Entry(parent)
            self.button = Button(parent, text="Cal", command=self.call_command)
    
        def call_command(self):
            value = self.entry.get()
            self.command(value)
    

    You would use it something like this:

    def some_function(self, value):
        print "the value is", value
    ...
    for calVal in calibration:
        le = LabelEntry(frame, 
                        text="Set aplitud to " + calVal, 
                        command=self.some_function)
        le.label.grid(...)
        le.entry.grid(...)
        le.button.grid(...)