Python Forum
Find Checkbutton State
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Find Checkbutton State
#1
I am creating a form to have a user input information for making labels. One of the issues I am running into is that I cant figure out how to call for the check button state after the finished button is clicked.

from tkinter import *
from tkinter import ttk


class Stability_Label_Creator():
    def __init__(self, master):
        
        self.notebook = ttk.Notebook(master)
        self.notebook.pack()

        # Add tabs to main window
        self.formulations = ttk.Frame(self.notebook)
        self.stabilityschedule = ttk.Frame(self.notebook)
        self.notebook.add(self.formulations, text = 'Formulations')
        self.notebook.add(self.stabilityschedule, text = 'Stability Schedule')
        
        ttk.Label(self.formulations, text = 'Formulation Name').grid(row = 0, column = 3)
        ttk.Label(self.formulations, text = 'Formulation Lot Number').grid(row = 0, column = 4)
        for x in range(1, 26):
            RowLabel = 'RowLabel' + str(x)
            RowLabel = ttk.Label(self.formulations, text = x)
            RowLabel.grid(row = x, column = 1)

            FormulationVar = 'FormulationVar' + str(x)
            FormulationVar = BooleanVar()
            Formulation = 'Formulation' + str(x)
            Formulation = ttk.Checkbutton(self.formulations, text = '', variable = FormulationVar, onvalue = True, offvalue = False)
            Formulation.grid(row = x, column = 2)
            FormulationVar.set(False)

            FormulationName = 'FormulationName' + str(x)
            FormulationName = ttk.Entry(self.formulations, width = 30)
            FormulationName.grid(row = x, column = 3)  

            FormulationLot = 'FormulationLot' + str(x)
            FormulationLot = ttk.Entry(self.formulations, width = 30)
            FormulationLot.grid(row = x, column = 4)

        self.NextButton = ttk.Button(self.formulations, text = 'Next', command = self.Next)
        self.NextButton.grid(row = 26, column = 4)

        ttk.Label(self.stabilityschedule, text = 'Time Point').grid(row = 0, column = 2)
        ttk.Label(self.stabilityschedule, text = 'Storage Conditions').grid(row = 0, column = 3, columnspan = 7)
        ttk.Label(self.stabilityschedule, text = 'Vials Per Time Point').grid(row = 0, column = 10)
        self.BackButton = ttk.Button(self.stabilityschedule, text = 'Back', command = self.Back)
        self.BackButton.grid(row = 26, column = 9)
        self.FinishedButton = ttk.Button(self.stabilityschedule, text = 'Finished', command = self.Finished)
        self.FinishedButton.grid(row = 26, column = 10)
        for x in range(1, 26):
            TimePointLabel = 'TimePointLabel' + str(x)
            TimePointLabel = ttk.Label(self.stabilityschedule, text = x)
            TimePointLabel.grid(row = x, column = 1)

            TimePoint = 'TimePoint' + str(x)
            TimePoint = ttk.Entry(self.stabilityschedule, width = 30)
            TimePoint.grid(row = x, column = 2) 

            VialsPerTimePoint = 'VialsPerTimePoint' + str(x)
            VialsPerTimePoint = ttk.Entry(self.stabilityschedule, width = 30)
            VialsPerTimePoint.grid(row = x, column = 10) 

        # Need to get the Check Box Text to be correct.  Right now they all say 60C
        StorCond = ['-20C', '5C', '25C', '30C', '40C', '50C', '60C']
        for x in range(1, 26):
            for y in range(3, 10):
                # for y in range(3, 10):
                StorageConditionsVar = 'StorageConditionsVar' + str(StorCond[y-3])
                StorageConditionsVar = BooleanVar()
                StorageConditions = 'StorageConditions' + str(StorCond[y-3])
                self.StorageConditions = ttk.Checkbutton(self.stabilityschedule, name = 'storageConditions' + str(StorCond[y-3]) + str(x),
                    text = str(StorCond[y-3]), variable = StorageConditionsVar, onvalue = True, offvalue = False)
                StorageConditionsVar.set(False)
                self.StorageConditions.grid(row = x, column = y)

                # print(self.StorageConditions.state())
    
    def Finished(self):
        print('Finished Button Clicked')
    
    def Next(self):
        # Moves to next tab in notebook
        self.notebook.select(1)
        # print(self.formulations.Formulation01.state())

    def Back(self):
        # Returns to first tab in notebook
        self.notebook.select(0)
    
    def print(self):
        print('Formulation Name: {}'.format(self.FormulationName01.get()))
        print('Formulation Selected: {}'.format(self.FormulationVar01.get()))

def main():            
    
    mainwindow = Tk()
    mainwindow.title('Stability Label Creator')
    app = Stability_Label_Creator(mainwindow)
    mainwindow.mainloop()

if __name__ == "__main__": main()
I some how need to find all the children text boxes on the Formulations frame in the note and determine which ones are checked.

Output:
Finished Button Clicked
Error:
Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\02260235\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__ return self.func(*args) File "c:/Users/02260235/Downloads/Test App/TkinterTest.py", line 79, in Finished for cb in self.formulations.findChild(self): AttributeError: 'Frame' object has no attribute 'findChild'
Reply
#2
You did not provide the code that produces the error.

You want to use winfo_children(). findChild is from Qt (and maybe otheres), not tkinter.

The easiest and most obvious answer to your dilemma is keep the reference to the check boxes (or better yet the BoolVar that is bound to the check box value). Then you don't have to search.
Reply
#3
I have seen one way is to create a dictionary and save the name as key and an IntVar as value, the checked box is 1.
here's a rewrite of your code hope it points you on path to success:
from tkinter import *
from tkinter import ttk
 
 
class Stability_Label_Creator():
    def __init__(self, master):
         
        self.notebook = ttk.Notebook(master)
        self.notebook.pack()
        self.checkbuttons= {}
 
        # Add tabs to main window
        self.formulations = ttk.Frame(self.notebook)
        self.stabilityschedule = ttk.Frame(self.notebook)
        self.notebook.add(self.formulations, text = 'Formulations')
        self.notebook.add(self.stabilityschedule, text = 'Stability Schedule')
         
        ttk.Label(self.formulations, text = 'Formulation Name').grid(row = 0, column = 3)
        ttk.Label(self.formulations, text = 'Formulation Lot Number').grid(row = 0, column = 4)
        for x in range(1, 26):
            RowLabel = 'RowLabel' + str(x)
            RowLabel = ttk.Label(self.formulations, text = x)
            RowLabel.grid(row = x, column = 1)
 
            FormulationVar = 'FormulationVar' + str(x)
            value_= IntVar()
            self.checkbuttons[FormulationVar]= value_
            self._Formulation = 'Formulation' + str(x)
            self._Formulation = ttk.Checkbutton(self.formulations, text = FormulationVar, variable = value_,
                                                )
            self._Formulation.grid(row = x, column = 2)
            
 
            FormulationName = 'FormulationName' + str(x)
            FormulationName = ttk.Entry(self.formulations, width = 30)
            FormulationName.grid(row = x, column = 3)  
 
            FormulationLot = 'FormulationLot' + str(x)
            FormulationLot = ttk.Entry(self.formulations, width = 30)
            FormulationLot.grid(row = x, column = 4)
 
        self.NextButton = ttk.Button(self.formulations, text = 'Next', command = self.Next)
        self.NextButton.grid(row = 26, column = 4)
 
        ttk.Label(self.stabilityschedule, text = 'Time Point').grid(row = 0, column = 2)
        ttk.Label(self.stabilityschedule, text = 'Storage Conditions').grid(row = 0, column = 3, columnspan = 7)
        ttk.Label(self.stabilityschedule, text = 'Vials Per Time Point').grid(row = 0, column = 10)
        self.BackButton = ttk.Button(self.stabilityschedule, text = 'Back', command = self.Back)
        self.BackButton.grid(row = 26, column = 9)
        self.FinishedButton = ttk.Button(self.stabilityschedule, text = 'Finished', command = self.Finished)
        self.FinishedButton.grid(row = 26, column = 10)
        for x in range(1, 26):
            TimePointLabel = 'TimePointLabel' + str(x)
            TimePointLabel = ttk.Label(self.stabilityschedule, text = x)
            TimePointLabel.grid(row = x, column = 1)
 
            TimePoint = 'TimePoint' + str(x)
            TimePoint = ttk.Entry(self.stabilityschedule, width = 30)
            TimePoint.grid(row = x, column = 2) 
 
            VialsPerTimePoint = 'VialsPerTimePoint' + str(x)
            VialsPerTimePoint = ttk.Entry(self.stabilityschedule, width = 30)
            VialsPerTimePoint.grid(row = x, column = 10) 
 
        # Need to get the Check Box Text to be correct.  Right now they all say 60C
        StorCond = ['-20C', '5C', '25C', '30C', '40C', '50C', '60C']
        for x in range(1, 26):
            for y in range(3, 10):
                # for y in range(3, 10):
                StorageConditionsVar = 'StorageConditionsVar' + str(StorCond[y-3])
                StorageConditionsVar = BooleanVar()
                StorageConditions = 'StorageConditions' + str(StorCond[y-3])
                self.StorageConditions = ttk.Checkbutton(self.stabilityschedule, name = 'storageConditions' + str(StorCond[y-3]) + str(x),
                    text = str(StorCond[y-3]), variable = StorageConditionsVar, onvalue = True, offvalue = False)
                StorageConditionsVar.set(False)
                self.StorageConditions.grid(row = x, column = y)
 
                # print(self.StorageConditions.state())
     
    def Finished(self):
        print('Finished Button Clicked')
        for key,value in self.checkbuttons.items():
            if value.get():
                print(key) #prints the name of the checked box
     
    def Next(self):
        # Moves to next tab in notebook
        self.notebook.select(1)
        
 
    def Back(self):
        # Returns to first tab in notebook
        self.notebook.select(0)
     
    
 
def main():            
     
    mainwindow = Tk()
    mainwindow.title('Stability Label Creator')
    app = Stability_Label_Creator(mainwindow)
    mainwindow.mainloop()
 
if __name__ == "__main__":
    main()
Reply
#4
Here's a working example:

from tkinter import *
from tkinter import ttk
from CreateDict import CreateDict
import sys

 
class Stability_Label_Creator():
    def __init__(self, master):
        cd = CreateDict()
        self.notebook = ttk.Notebook(master)
        self.notebook.pack()
 
        # Checkbox Storage for Formulation and Storage Conditions

        self.Formulation_data = {}

        self.StorCond = ['-20C', '5C', '25C', '30C', '40C', '50C', '60C']
        self.StorageCondition_data = {}        
        
        self.formulations = ttk.Frame(self.notebook)
        self.stabilityschedule = ttk.Frame(self.notebook)
        self.notebook.add(self.formulations, text = 'Formulations')
        self.notebook.add(self.stabilityschedule, text = 'Stability Schedule')

        ttk.Label(self.formulations, text = 'Formulation Name').grid(
            row = 0, column = 3)
        ttk.Label(self.formulations, text = 'Formulation Lot Number').grid(
            row = 0, column = 4)

        for x in range(1, 26):
            rnode = cd.add_node(self.Formulation_data, x)
            cd.add_cell(rnode, 'label', ttk.Label(self.formulations, text=x))
            cd.add_cell(rnode, 'checkstatus', BooleanVar())
            # RowLabel = ttk.Label(self.formulations, text = x)
            rnode['label'].grid(row=x, column=1)

            cd.add_cell(rnode, 'checkbox', ttk.Checkbutton(self.formulations, text='', 
                variable=rnode['checkstatus'], onvalue=True, offvalue=False, 
                command= lambda val = x: self.formulation_box_checked(val)))
            # btn['command'] = lambda arg1="Hello", arg2=" ", arg3="World!" : print(arg1 + arg2 + arg3)
            rnode['checkbox'].grid(row=x, column=2)
            rnode['checkstatus'].set(False)

            cd.add_cell(rnode, 'entry1', ttk.Entry(self.formulations, width=30))
            rnode['entry1'].grid(row=x, column=3)

            cd.add_cell(rnode, 'entry2', ttk.Entry(self.formulations, width=30))
            rnode['entry2'].grid(row=x, column=4)
 
        self.NextButton = ttk.Button(self.formulations, text = 'Next', command = self.Next)
        self.NextButton.grid(row = 26, column = 4)
 
        ttk.Label(self.stabilityschedule, text = 'Time Point').grid(row = 0, column = 2)
        ttk.Label(self.stabilityschedule, text = 'Storage Conditions').grid(row = 0, column = 3, columnspan = 7)
        ttk.Label(self.stabilityschedule, text = 'Vials Per Time Point').grid(row = 0, column = 10)

        self.BackButton = ttk.Button(self.stabilityschedule, text = 'Back', command = self.Back)
        self.BackButton.grid(row = 26, column = 9)
        self.FinishedButton = ttk.Button(self.stabilityschedule, text = 'Finished', command = self.Finished)
        self.FinishedButton.grid(row = 26, column = 10)

        for x in range(1, 26):
            rnode = cd.add_node(self.StorageCondition_data, x)

# ..|....|....|....|....|....|....|....|....|....|....|....|....|....|....|....|
            cd.add_cell(rnode, 'label', ttk.Label(self.stabilityschedule, text=x))
            cd.add_cell(rnode, 'checkstatus', BooleanVar())
            rnode['label'].grid(row=x, column=1)
            cd.add_cell(rnode, 'entry1', ttk.Entry(self.stabilityschedule, width=30))
            rnode['entry1'].grid(row=x, column=10)
 
            col = 3
            for sc in self.StorCond:
                inode = cd.add_node(rnode, sc)
                cd.add_cell(inode, 'checkstatus', BooleanVar())
                cd.add_cell(inode, 'checkbox', ttk.Checkbutton(self.stabilityschedule,
                    text=sc, variable=inode['checkstatus'], onvalue=True, offvalue=False,
                    command= lambda val = x, val1=sc: self.storageConditions_box_checked(val, val1)))
                inode['checkbox'].grid(row=x, column=col)
                col += 1

    def formulation_box_checked(self, x):
        if self.Formulation_data[x]['checkstatus'].get():
            print(f"checkbox {x} clicked")
        else:
            print(f"checkbox {x} un-clicked")


    def storageConditions_box_checked(self, x, sc):
        if self.StorageCondition_data[x][sc]['checkstatus'].get():
            print(f"row {x}, checkbox {sc} clicked")
        else:
            print(f"row {x}, checkbox {sc} un-clicked")

    def Finished(self):
        print('Finished Button Clicked')
     
    def Next(self):
        # Moves to next tab in notebook
        self.notebook.select(1)
        # print(self.formulations.Formulation01.state())
 
    def Back(self):
        # Returns to first tab in notebook
        self.notebook.select(0)
     
    def print(self):
        print('Formulation Name: {}'.format(self.FormulationName01.get()))
        print('Formulation Selected: {}'.format(self.FormulationVar01.get()))
 
def main():                 
    mainwindow = Tk()
    mainwindow.title('Stability Label Creator')
    app = Stability_Label_Creator(mainwindow)
    mainwindow.mainloop()
 
if __name__ == "__main__":
    main()
You will also need CreateDict.py here:
#  Author: Larz60+ Nov 22, 2018
import os


class CreateDict:
    def __init__(self):
        os.chdir(os.path.abspath(os.path.dirname(__file__)))

    def new_dict(self, dictname):
        setattr(self, dictname, {})

    def add_node(self, parent, nodename):
        node = parent[nodename] = {}
        return node

    def add_cell(self, nodename, cellname, value):
        cell =  nodename[cellname] = value
        return cell

    def display_dict(self, dictname, level=0):
        indent = " " * (4 * level)
        for key, value in dictname.items():
            if isinstance(value, dict):
                print(f'\n{indent}{key}')
                level += 1
                self.display_dict(value, level)
            else:
                print(f'{indent}{key}: {value}')
            if level > 0:
                level -= 1


def testit():
    cd = CreateDict()

    cd.new_dict('CityList')

    boston = cd.add_node(cd.CityList, 'Boston')
    bos_resturants = cd.add_node(boston, 'Resturants')

    spoke = cd.add_node(bos_resturants, 'Spoke Wine Bar')
    cd.add_cell(spoke, 'Addr1', '89 Holland St')
    cd.add_cell(spoke, 'City', 'Sommerville')
    cd.add_cell(spoke, 'Addr1', '02144')
    cd.add_cell(spoke, 'Phone', '617-718-9463')

    highland = cd.add_node(bos_resturants, 'Highland Kitchen')
    cd.add_cell(highland, 'Addr1', '150 Highland Ave')
    cd.add_cell(highland, 'City', 'Sommerville')
    cd.add_cell(highland, 'ZipCode', '02144')
    cd.add_cell(highland, 'Phone', '617-625-1131')

    print(f'\nCityList Dictionary')
    cd.display_dict(cd.CityList)
    print(f'\nraw data: {cd.CityList}')

if __name__ == '__main__':
    testit()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Checkbutton writing selection to file blakefindlay 1 2,078 Jan-28-2021, 01:56 PM
Last Post: deanhystad
Question [Tkinter] Checkbutton clicks events does not update visually. nicolaask 1 2,919 Dec-20-2020, 06:11 PM
Last Post: nicolaask
  [Tkinter] How to insert 'Checkbutton' to 'Treeview' and associate each item? water 2 12,995 Dec-19-2020, 05:24 PM
Last Post: water
  [tkinter] not getting checkbutton value when clicked OogieM 5 5,882 Sep-20-2020, 04:49 PM
Last Post: deanhystad
  [Tkinter] ttk.Checkbutton set on/off ifigazsi 5 10,305 Apr-04-2020, 07:34 PM
Last Post: deanhystad
  tkinter checkbutton if checked MC2020 2 5,925 Jan-21-2020, 07:08 PM
Last Post: joe_momma
  [Tkinter] Can't seem to get the current state of a checkbutton. p_hobbs 6 3,268 Nov-07-2019, 11:38 PM
Last Post: p_hobbs
  [Tkinter] Create a set of checkbutton widgets and refer to every one of them individually? Mariano 1 2,675 Apr-11-2019, 06:20 PM
Last Post: woooee
  doing something after been checked a checkbutton gray 1 4,236 Feb-18-2017, 05:11 PM
Last Post: Axel_Erfurt

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020