Question

I'm using tkinter to create a "grid" like structure that displays the contents of an eeprom in entry fields.

for byteRow in range (0, 16, 1):
    for byteColumn in range (0, 16, 1):
        byteEeprom = StringVar()
        self.byteEepromArray.append(byteEeprom)
        self.entryEepromArray.append(ttk.Entry(rawEeprom, width=3, textvariable = self.byteEepromArray[byteColumn+(16*byteRow)]))
        self.entryEepromArray[byteColumn+(16*byteRow)].grid(column = byteColumn, row = byteRow+2, sticky = (N, W))

The above all works fine and is populated in a function using self.byteEepromArray[byte].set() but I'm trying to change the code so that if someone wanted to change one of the eeprom locations they would change the contents of one of the entry fields, press return and a function would be called to talk to the eeprom. Unfortunately what is happening is that the function makeRawProbe is being called when the script is imported rather than waiting for the event to happen.

 for byteRow in range (0, 16, 1):
        for byteColumn in range (0, 16, 1):
            byteEeprom = StringVar()
            self.byteEepromArray.append(byteEeprom)
            self.entryEepromArray.append(ttk.Entry(rawEeprom, width=3, textvariable = self.byteEepromArray[byteColumn+(16*byteRow)]))
            self.entryEepromArray[byteColumn+(16*byteRow)].grid(column = byteColumn, row = byteRow+2, sticky = (N, W))
            self.entryEepromArray[byteColumn+(16*byteRow)].bind('<Return>', self.makeRawProbe(byteColumn+(16*byteRow)))

I've tried changing to in case it was picking up on something weird from the command line but the same thing happens. I guess I'm doing something dumb but just cant see what it is, please can someone point me in the right direction?

Was it helpful?

Solution

The argument to bind must be a reference to a function. When you do something like:

...bind('<Return>', self.makeRawProbe(byteColumn+(16*byteRow)))

... then you are actually calling self.makeRawProbe(...), and the result of that call is what is being assigned to the binding.

Instead, you need to pass a reference to the function itself. Since you need to pass arguments to the function you will need to use something like lambda or functools.partial or a factory of some sort. I'm partial to lambda since it doesn't requiring pulling in another library.

For example:

value = byteColumn+(16*byteRow)
...bind('<Return>', lambda event, idx=value: self.makeRawProbe(idx))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top