1

The following code allows me to add/remove France/Italy from a list when clicked on a tkinter checkbox. Rather than passing 0 or 1 to the Add_France function, is it possible to pass through a string "France"? Thanks

My_list = []

root = Tk()

Country_Variable1 = tkinter.IntVar()
Country_Variable2 = tkinter.IntVar()

def Add_France():
    if Country_Variable1.get() == 1:
        My_list.append("France")
    if Country_Variable1.get() == 0:
        My_list.remove("France")
    print (My_list)

def Add_Italy():
    if Country_Variable2.get() == 1:
        My_list.append("Italy")
    if Country_Variable2.get() == 0:
        My_list.remove("Italy")
    print (My_list)

check1 = Checkbutton(root, text='France',variable=Country_Variable1, onvalue=1, offvalue=0, command=Add_France)
check2 = Checkbutton(root, text='Italy',variable=Country_Variable2, onvalue=1, offvalue=0, command=Add_Italy)

check1.pack()
check2.pack()

root.mainloop()
3
  • 1
    You can use a string with Country_Variable1 = tkinter.StringVar() but what would you use for offvalue ? Commented Jan 12, 2022 at 18:56
  • can I ask the objective here? I mean what are you looking for the string? Is it to optimise the code or is there something specific that you want to achieve? Commented Jan 12, 2022 at 21:33
  • To optimize the code, I have a lot more countries than just France & Italy so wondering if there is a better way. I'm trying to use the checkboxes to add/remove Countries to a list. The code will then later on loop through whatever countries were selected. Commented Jan 12, 2022 at 21:47

2 Answers 2

1

You have control over onvalue and offvalue with Checkbutton, so you can play around with the value that it returns in each state. In the below example, you can see how to make checkbutton based on inputs inside the list(assuming it is a list of strings of characters always):

from tkinter import *

root = Tk()

def process(var,text):
    try:
        val = int(var.get()) # If not selected it will give 0 as int, which will trigger `else` block
    except ValueError:
        val = var.get()

    if val: # if val is not empty, ie, if val is any selected value
        slct_ctry_lst.append(val)
    else: # if val is 0 
        slct_ctry_lst.remove(text) # Remove the corresponding text from the list

    print(slct_ctry_lst)

slct_ctry_lst = []
countries = ['France','Italy','China','Russia','India']

for idx,i in enumerate(countries):
    var = StringVar(value=" ")
    Checkbutton(root,text=i,variable=var,command=lambda i=i,var=var: process(var,i),onvalue=i).grid(row=0,column=idx)

root.mainloop()

Thought it would be easier, but maybe not suitable, with ttk.Combobox:

def process(e):
    val = e.widget.get()
    if val in slct_ctry_lst: # If val present inside the list
        slct_ctry_lst.remove(val) # Remove it
    else: 
        slct_ctry_lst.append(val)
    
    print(slct_ctry_lst)

slct_ctry_lst = []
countries = ['France','Italy','China','Russia','India']

cbox = ttk.Combobox(root,values=countries,state='readonly')
cbox.pack(padx=10,pady=10)
cbox.set('Select a country')

cbox.bind('<<ComboboxSelected>>',process)
Sign up to request clarification or add additional context in comments.

Comments

1

If the objective here is to make the code reusable for multiple countries, here is initial idea, this can be improved further. Basically, I am using lambda expression here to the callback command function and passing the country name. Created a separate function to create a checkbox which is generic for all the countries. Now to add a new country to the list all you need to do is add an element to the available_country_list You can make available_country_list global or can pass that as an argument to the list_countries function.

import tkinter
from tkinter import Checkbutton

selected_country_list = []


def select_country(country_name, variable):
    global selected_country_list
    print(variable)
    if variable.get() == 1:
        selected_country_list.append(country_name)
    elif variable.get() == 0:
        selected_country_list.remove(country_name)
    print (selected_country_list)


def create_checkbox(parent, country_name):
    country_var = tkinter.IntVar()
    country_check = Checkbutton(parent, text=country_name, variable=country_var,
                                onvalue=1, offvalue=0,
                                command=lambda: select_country(country_name, country_var))
    country_check.pack()


def list_countries(root):
    available_country_list = ["France", "Italy"]
    for country in available_country_list:
        create_checkbox(root, country)


def load(root):
    # Create list of country checkboxes
    list_countries(root)


def start():
    root = tkinter.Tk()
    root.after(100, load, root)  # Enable lazy loading of your components
    root.mainloop()


if __name__ == '__main__':
    start()

3 Comments

Why did you have to overcomplicate the answer?
yeh.. you may be right.. I might have overcomplicated this.. sorry about that.. I was just trying to help
It is helpful indeed.

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.