-1

I am building a spreadsheet of sorts. One of the columns has an OptionMenu in each cell. Each OptionMenu has its own class member StringVar (in an array) associated with it. All OptionMenus use a single callback. How do I know which OptionMenu (and its associated StringVar) was selected?

    self.event_option_string_var = []
 .
 .
 .

        for col in range(HeaderCol.MAX_COL):
            if col == TransactionsGrid.DATE_COL.col:
                widget = DateEntry(self.frame_main, selectmode='day')
                widget.grid(row=1, column=1, padx=0)
                Entry(widget).configure(highlightthickness=0)
            elif col == TransactionsGrid.EVENT_COL.col:
                string_var = StringVar(self.root)
                string_var.set('Select an Event')
                self.event_option_string_var.append(string_var)
                widget = OptionMenu(self.frame_main, string_var,
                                    string_var,
                                    *TenantEvent.TENANT_EVENTS,
                                    command=self.option_changed)

            else:
                widget = Entry(self.frame_main)
                widget.configure(highlightthickness=0)
            button_row.append(widget)
            widget.grid(column=col, row=row + 2, sticky="")

 .
 .
 .


def option_changed(self, *args):
    self.event_option_string_var['text'] = f'You selected: {self.event_option_string_var.get()}'
jordanthompson
  • 888
  • 1
  • 12
  • 29
  • When `def option_changed(self, *args):` is called, did you try to check what `args` contains? Did you try to read the documentation for the `command` keyword argument, in order to see if there is any useful information there? Alternately, did you try binding information to the callback yourself? – Karl Knechtel Mar 03 '23 at 21:42
  • @KarlKnechtel I did and the only thing args contains is the string that changed. How do you bind more information than the StringVar? I am used to callbacks (in other languages) that contain references to whatever you like, but I don't see any way to do this in python/tkinter – jordanthompson Mar 03 '23 at 22:09
  • I'm out of close votes for today, but if that's the underlying question then [Python Argument Binders](https://stackoverflow.com/questions/277922) is the canonical. – Karl Knechtel Mar 03 '23 at 22:36

1 Answers1

0

@karl knechtel solved this for me (I completely forgot about partial!)

Here is how I handled it:

from functools import partial
.
.
.
                string_var = StringVar(self.root)
                string_var.set('Select an Event')
                widget = OptionMenu(self.frame_main, string_var,
                                    'Change me',
                                    *TenantEvent.TENANT_EVENTS,
                                    command=partial(self.option_changed, row))

and in the callback:

def option_changed(self, *args):
    print(f'row is: {args[0]}, values is:{args[1]}')
jordanthompson
  • 888
  • 1
  • 12
  • 29
  • FWIW, I changed to QT and it is SOOoooo much easier (less code, more intuitive) and it looks like a real GUI (at least on Windows) – jordanthompson Mar 04 '23 at 21:34