1

I'm learning to use tkinter/ttk (im still a noob when it comes to GUI programming) and i'm having a problem that i can't quite wrap my head around.

What I'm trying to do is create a program, that gives user multiple checkboxes and based on what user checks, it goes and fetches some data from the internet. I've made few checkboxes for testing and tied them all into same function.

The problem I'm having is that while this source claims that when using command option in ttk.Checkbox, the function will be called every time the state of the checkbox changes (i presume change = tick/untick) and I just don't see it happening (it might ofc be just me not understanding it correctly). I'll copy-paste the code i'm trying to run (i removed formating, images etc to keep it smaller and more simple): I'm using Python v3.4.2 and Tcl/Tk v8.6)

from tkinter import *
from tkinter import ttk

nimekiri = []

def specChoice(x):
    choice = wtf[x].get()
    print("step 1") #temp check 1 (to see from console if and when the program reaches this point)
    if len(choice) != 0:
        print("step 2") #temp check 2
        spec = choice.split(" ")[0]
        tic = choice.split(" ")[1]
        if tic == "yes":
            print("step 3") #temp check 3
            nimekiri.append(spec)
        elif tic == "no":
            if spec == nimekiri[x].get():
                nimekiri.remove(spec)

    
root = Tk()
# Frames
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))

spec_frame = ttk.Labelframe(root, text="Placeholder for txt: ", padding="9 9 12 12")
spec_frame.grid(column=0, row=0, sticky=(N, W, E, S))

results_frame = ttk.Labelframe(root, text="Results: ", padding="3 3 12 12")
results_frame.grid(column=10, row = 0, sticky=(N, W, E, S))

# Text Labels
ttk.Label(spec_frame, text="Question:").grid(column=1, row=1, sticky=(N,S,W))
ttk.Label(spec_frame, text="Choice 1").grid(column=1, row=2, sticky=(N,S,W))
ttk.Label(spec_frame, text="Choice 2").grid(column=1, row=3, sticky=(N,S,W))

# Checkboxes etc
results_window = Text(results_frame, state="disabled", width=44, height = 48, wrap="none")
results_window.grid(column=10, row=1, sticky=W)

wtf = []
wtf.append(StringVar())
wtf.append(StringVar())
wtf[0].set("choice1 no")
wtf[0].set("choice2 no")
ttk.Checkbutton(spec_frame, command=specChoice(0), variable=wtf[0],
                onvalue="choice1 yes", offvalue="choice1 no").grid(column=0, row=2, sticky=E)
ttk.Checkbutton(spec_frame, command=specChoice(1), variable=wtf[1],
                onvalue="choice2 yes", offvalue="choice2 no").grid(column=0, row=3, sticky=E)


#wtf[0].trace("w", specChoice2(0))

root.mainloop()

In above code, what i'm expecting to happen is when user tics Choice 1 box, the value of wtf[0] would be changed and specChoice(0) function would be run, but with the print() functions I added it seems that the specChoice is only run when i start the program and thus the program never reaches #temp check 3. (It didn't even reach # temp check 2 before i added default values to the checkbox variables)

1 Answer 1

1

When you use command=specChoice(0), you assign the return value of a call to specChoice(0) to the command, which is None. You need to pass a function to command, not a function call, like command=specChoice.
However, this way you cannot pass function arguments. To overcome this, you can create an anonymous function which calls specChoice(0) like:

ttk.Checkbutton(spec_frame, command = lambda: specChoice(0), ...).grid(...)

This is basically doing:

def anonymous_function_0():
    specChoice(0)

ttk.Checkbutton(spec_frame, command=anonymous_function_0, ...).grid(...)

but it does it on one line.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks... that worked like a charm. PS: I saw lambda being used somewhere else as well, but the question it was used in had such complex code that I didn't research it thoroughly)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.