1

I am building a gui in tkinter with a list task_list = [].

Tasks are appended to/deleted from the list in the gui.

I want a window with checkboxes for every item in the list.

So if there's 10 items in the list, there should also be 10 checkboxes. If there's 5 items in the list, there should be 5 corresponding checkboxes.

Can this be done?

I can't find anything on it

Thanks!

2
  • 1
    this can certainly be done, just loop over the list using a for loop and each iteration create a Radiobutton and pack it, that would be the basic stuff at least Commented May 12, 2021 at 22:54
  • 1
    Yes it can be done. Just iterate over the items in a list, creating a checkbutton for each. Commented May 12, 2021 at 23:23

2 Answers 2

2

Here.

from tkinter import *
task_list=["Call","Work","Help"]
root=Tk()
Label(root,text="My Tasks").place(x=5,y=0)
placement=20
for tasks in task_list:
    Checkbutton(root,text=str(tasks)).place(x=5,y=placement)
    placement+=20
root.mainloop()

Using grid.

from tkinter import *
task_list=["Call","Work","Help"]
root=Tk()
Label(root,text="My Tasks").grid(row=0,column=0)
placement=3
for tasks in task_list:
    Checkbutton(root,text=str(tasks)).grid(row=placement,column=0,sticky="w")
    placement+=3
root.mainloop()
Sign up to request clarification or add additional context in comments.

9 Comments

dude, there is pack() option, why wouldn't You use that in this case, it would save some space to avoid writing placement and incementing it? also no need to use str(tasks) because tasks is already a string
@Sujay Thank you - I have used .grid in my entire GUI, is there any way to make use of what you just showed me but with grid placement? I tried it and it only shows 1 check button (the newest task) in the grid I specify, which makes sense I guess.
@KarimLoberg for grid it would be possible to for index, item in enumerate(task_list): and then Checkbutton(master, **options).grid(column=0, row=index) and btw it is possible to mix up layout managers in different containers so for example if one frame uses grid() a different frame could use pack() if need be
**options part confuses me and the item part is just what was previously named tasks, right?
@KarimLoberg the **option and master part can be ignored, basically instead of that You would write what the OP wrote there and yes item is the same as tasks in my given loop. To get the selected value You would need to use a StringVar and assign it to the value attribute of Checkbutton, tho note that for each Checkbutton there has to be a separate StringVar. Then You can just use .get() method of StringVar. (I will just write an answer in a while and explain this)
|
1

Here is my code for this issue:

from tkinter import Tk, Checkbutton, IntVar, Frame, Label
from functools import partial

task_list = ['Task 1', 'Task 2', 'Task 3', 'Work', 'Study']


def choose(index, task):
    print(f'Selected task: {task}' if var_list[index].get() == 1 else f'Unselected task: {task}')


root = Tk()

Label(root, text='Tasks').grid(column=0, row=0)

frame = Frame(root)
frame.grid(column=0, row=1)

var_list = []

for index, task in enumerate(task_list):
    var_list.append(IntVar(value=0))
    Checkbutton(frame, variable=var_list[index],
                text=task, command=partial(choose, index, task)).pack()

root.mainloop()

First I would like to mention that it is possible to mix layout manager methods like in this example. The main window uses grid as layout management method and I have gridded a frame to the window, but notice that Checkbuttons are getting packed, that is because frame is a different container so it is possible to use a different layout manager, which in this case makes it easier because pack just puts those checkbuttons one after another.

The other stuff:
There is the task list which would contain the tasks.

Then I have defined a function choose() this function prints out something. It depends on a variable. The comparison happens like this: print out this if value is this else print out this. It is just an if/else statement in one line and all it checks is if the IntVar in that list in that specific index is value 1 so "on". And there are two argument this function takes in: index and task. The index is meant to get the according IntVar from the var_list and the task is meant to display what tasks was chosen or unchosen.

Then the simple root = Tk() and root.mainloop() at the end.

Then is the label that just explains it.

Then the frame and here You can see that both label and frame were gridded using .grid()

Then the var_list = [] just creates an empty list.

Then comes the loop:
It loops over each item in the task_list and extracts the index of that item in the list and the value itself. This is done by using enumerate() function.

Each iteration appends a IntVar(value=0) to the var_list and since this appending happens at the same time as the items are read from the task_list the index of that IntVar in the list is the same as the current item in the task_list so that same index can be used for access.

Then a Checkbutton is created, its master is the frame (so that .pack() can be used) and the text=task so it corresponds to task name, the variable is set as a specific item in the var_list by index and this all has to be done so that a reference to that IntVar is kept. Then comes command=partial(choose, index, task) which may seem confusing but all partial does is basically this function will now execute always with the variables just given so those variables will always be the same for this function for this Checkbutton. And the first argument of partial is the function to be executed and next are arguments this function takes in. Then the Checkbutton gets packed.

If You have any questions ask.

Useful sources:

Comments

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.