0

I have a column list colList = ['A','B','C','D'] which is displayed along with checkbox to user, user checks the checkbox and clicks submit button. On submit i want to get the column of the check values only.

I am using Tkinter, Grid structure.

Code is as follows.

from tkinter import filedialog
from tkinter import *
import tkinter as tk


def command_to_extract():
    print('Extract button pressed')

#this function will display which checkbox is checked and display the column name - But I am not able to write the check condition for checking the value of checkbox

root = Tk()

button3 = Button(text="Extract", command=command_to_extract, width=30, anchor=NW)
button3.grid(row=4, column=4)

lbl31 = Label(master=root, text="Select the column(s) for output csv file", width=30, anchor=NW)
lbl31.grid(row=5, column=2)

colList = ['A','B','C','D']

columnDictionary = { i : colList[i] for i in range(0, len(colList) ) } # To Make a dictionary from a List

p = 0 #variable for column

#this double for loop for 2X2 display of checkbox

for i in range(0, 2): #row      
    for j in range(0, 2): #column
        Checkbutton(master=root, text = colList[p], variable = var[], onvalue = 1, offvalue = 0, width=40, anchor=NW).grid(row = i, column = j)

        p = p + 1

mainloop()

Problem arises when i need to select only few checkbox, then how to distinguish one checkbox with other. Also i need to get the column name such as weither variable = var[] to use or some other way. Please help me out.

David Jones
  • 4,766
  • 3
  • 32
  • 45
Rink16
  • 138
  • 12
  • Checkbutton returns an object. Use variables or list to store the objects for further maniputation. Good luck! – LazyCoder Jul 26 '19 at 10:50
  • You can add `name` parameters to your checkboxes (`name="unique_name"`) and then simply check the name. – Ardweaden Jul 26 '19 at 10:51
  • this `variable = var[]` in `for loop` is not working as it works in HTML – Rink16 Jul 26 '19 at 10:55
  • @Ardweaden Is Name parameter can be used in `Checkbutton()`? in python tkinter – Rink16 Jul 26 '19 at 10:58
  • @SANTOSHKUMARDESAI please explain little more as I am new in python – Rink16 Jul 26 '19 at 11:01
  • As far as I know, `name` can be used in any Tkinter `Widget`. I'd simply pass something like `name="{}:{}".format(i,j)` to each `Checkbutton`. – Ardweaden Jul 26 '19 at 11:01
  • @Ardweaden then what for check condition? how it can be done as i following this link https://www.tutorialspoint.com/python/tk_checkbutton – Rink16 Jul 26 '19 at 11:03
  • @Ardweaden then what could be the check condition for whether the checkbox is checked or not. If i use `for item in colList: if var1.get(): print(var1)` – Rink16 Jul 26 '19 at 11:08
  • These might be useful: https://stackoverflow.com/questions/41291779/how-to-get-widget-name-in-event and https://stackoverflow.com/questions/8894841/is-it-possible-to-search-widget-by-name-in-tkinter – Ardweaden Jul 26 '19 at 11:14
  • You can check whether they are checked or not with class method `.state()`. – Ardweaden Jul 26 '19 at 11:17
  • @Ardweaden what could be the IF condition if we try to access the `name` variable for `colList` using the above said comment `name="{}:{}".format(i,j)`? – Rink16 Jul 26 '19 at 11:22
  • I am not sure what exactly you mean. You have to have some function binded to the widget, so that it fires when user makes an action, such as checking the box. That function is passed an `event` and you can get the identifying `name` from it. – Ardweaden Jul 26 '19 at 11:29
  • yes that's right but how this `name="{}:{}".format(i,j)` is working i want to know this – Rink16 Jul 26 '19 at 11:31

2 Answers2

1
from functools import partial

optionsticked = []
def callback(name):
    if name in optionsticked:
        optionsticked.remove(name)
        optionsticked.sort()
        print(optionsticked)
        return
    optionsticked.append(name)
    optionsticked.sort()
    print(optionsticked)

for i in range(0, 2): #row
    for j in range(0, 2): #column
        name = colList[p]
        Checkbutton(master=root, text = name, onvalue = 1, offvalue = 0, width=40, anchor=NW, command = partial(callback,name) ).grid(row = i, column = j)
        p += 1

mainloop()

So here I've just used the command function of the checkbutton, so that when it detects a press of the checkbutton, it passes the name of the button to the callback function, which appends the button to a list. If the button is unticked, it is removed. This should work for as many buttons as you wish and all you have to do is export the values of that list to a csv.

I've added the name of the button as an explicit variable within the for loop so that it can be passed to the function, and also imported functools.partial to pass variables to the callback function.

Another minor change was removing the variable = var[] part, as this didn't seem to do anything.

Hope this was the question you asked!

CodeBoi
  • 26
  • 3
  • it gives an error for `partial()`, `NameError: name 'partial' is not defined` – Rink16 Jul 26 '19 at 12:22
  • In the text below I said to import partial from functools, but I've added this to the answer to make it clearer. Sorry for the ambiguity! It should work now though. – CodeBoi Jul 26 '19 at 13:49
  • How to make if we try to have a button which make all checkbox checked by select all? Or set to by default checked? – Rink16 Jul 29 '19 at 07:28
  • Is there any id to assign to checkbox which we access to make all the checkbox checked on select all button click. – Rink16 Jul 29 '19 at 07:34
  • I couldn't quite figure it out, but you'd have to do a restructure. Placing the buttons into a list/dictionary, then setting the command on click to a function that loops over that list. The loop will then call i.select on each button. This checks each button, but bypasses my initial method. You then have to find a way to identify whether the button is pressed through looking at the specific IntVar for each button (either 1 or 0). The answer below me would probably do well at this, but the code as it is would definitely require a restructure. I'd recommend opening another question. – CodeBoi Jul 29 '19 at 17:05
  • i think if a checkbutton just refreshes the position with new checkbutton which are unchecked previously. – Rink16 Jul 30 '19 at 06:30
1

The simplest solution is to store the variables in a dictionary.

vars = {}
for row in range(0, 2):      
    for column in range(0, 2):
        vars[(row,column)] = IntVar()
        Checkbutton(..., variable=vars[(row,column)], ...)

You can then access the checkbutton for each row and column with vars[(row, column)].

def command_to_extract():
    print('Extract button pressed')
    for row in range(0,2):
        for column in range(0,2):
            var = vars[(row, column)]
            print("{},{}: {}".format(row, column, var.get())
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685