0

I am new to python and have a task to take input from a listbox and create radiobuttons for each entry. In my code I am able to create the radio buttons but they don't function when I click on them i.e. in this case they don't print "hello" and the number i. Here's the code:

def generateGraph():
    w = Toplevel(bg = "grey")
    w.resizable(0,0)
    frameData = Frame(w, bg="grey", padx=10, pady=10)
    frameData.grid(row = 0, column=0, pady = 1, padx = 1, sticky = N+E+S+W)
    InputLabel = Label(frameData, text="Inputs:", bg="grey")
    InputLabel.grid(row=1, column=0, padx=10, sticky=N+E+S+W)
    OutputLabel = Label(frameData, text="Outputs:", bg="grey")
    OutputLabel.grid(row=1, column=1, padx=10, sticky=N+E+S+W)

    i=0
    c=[]
    inputVar = IntVar()
    while(InputBox.get(i)):
        c.append(Radiobutton(frameData, text=InputBox.get(i), variable=inputVar, value = i, background="grey", command= hello(i)))
        c[i].grid(row = i+2, column = 0, sticky = W)
        i=i+1
    if makemodal:
        w.focus_set()
        w.grab_set()
        w.wait_window()
def hello(i):
    print("hello %d" %i)

Please help and thanks in advance.

Vishesh
  • 45
  • 1
  • 7
  • 1
    This isn't your first post - remember to indent your post properly and ensure everything that should be in a codeblock is – Jon Clements Jan 09 '13 at 00:22
  • Done. Thank you. Do you have any idea as to how we do it? – Vishesh Jan 09 '13 at 00:30
  • This isn't your problem (see my answer for that), but: Why are you attaching a `command` to a `Radiobutton`? That's not typical UI behavior. Normally radio buttons are there to select a value, which will be used by some other action later. – abarnert Jan 09 '13 at 00:32
  • As a side note: It's generally bad style to have 131-character-long lines, but that's especially true when you're posting on SO, which will force anyone to use a horizontal scrollbar just to see your code. – abarnert Jan 09 '13 at 00:37

1 Answers1

1

The problem is that you're calling hello(i) at the time of construction of the Radiobutton, not storing something to be called later:

    c.append(Radiobutton(frameData, text=InputBox.get(i), variable=inputVar, value = i, background="grey", command= hello(i)))

Since hello returns None, you're effectively storing command=None.

You need to store a callable here, like hello itself, (or a lambda or partial, or whatever), not the result of calling it.

For example:

    c.append(Radiobutton(frameData, text=InputBox.get(i), 
                         variable=inputVar, value = i, background="grey",
                         command=functools.partial(hello, i)))

Since you asked in the comments: Note that I used partial rather than lambda, because I want to bind in the value of i, not close over the variable i. Otherwise, you'd end up with, e.g., 5 radio buttons all bound to the same variable i with the value 4. There are other ways around this—use an explicit factory, do lambda x=i: hello(x) instead of lambda: hello(i), etc. To me, partial seems like the clearest and most explicit, but your mileage may vary. Anyway, there are dozens of questions on SO about this, but the answer to Scope of python lambda functions and their parameters seems particularly clear.

Community
  • 1
  • 1
abarnert
  • 354,177
  • 51
  • 601
  • 671
  • Yes, because you're creating a lambda for each `Radiobutton` that all close over the same `i` variable. There are dozens of SO questions about that, like [this one](http://stackoverflow.com/questions/938429/scope-of-python-lambda-functions-and-their-parameters), which will show you how to do the right thing. – abarnert Jan 09 '13 at 00:41
  • Thank you for that. But now the problem is that how do I know which radio button is clicked? i.e. now it's printing the last updated value of i whenever any button is clicked. – Vishesh Jan 09 '13 at 00:41
  • Thank you. I'll have a look at it. :) – Vishesh Jan 09 '13 at 00:43
  • @Vishesh: I edited the answer with the way I personally would do it. If that makes sense to you, great. But most people who don't think "partial evaluation is what I want" aren't going to understand why it's the right answer, so it's worth learning why this happens, and how the different solutions all work. – abarnert Jan 09 '13 at 00:50