samedi 13 mai 2023

How can I make my Checkbuttons independent of each other on Tkinter?

Running this on macOS Ventura Version 13.3.1 on python 3.9.12

I have an application with a total of 6 Checkbuttons (A-F). I have some rules to guide what happens with these Checkbuttons:

  • A and C should start off as being selected.

  • IF A and B are ever both deselected then I want to know that and perform a specific task.

  • One and only one of C-F should always be selected. If C is selected then I do not want user to be able to deselect it. If D-F is then selected, I want C to be deselected and activated.

My problem is that is seems like A and C are linked with each other (when A is selected/deselected so is C) while B, D, E, and F are linked with each other. How can I avoid this?

I tried using variations of both IntVar() and BooleanVar() for the Checkbutton variables. I know that global variables can be problematic but I am trying to solve this without using Classes if possible.

My code is shown below:

from tkinter import *

root = Tk()

#####
######Defining Checkbutton variables and initial values
#####
global a_var
global b_var
global c_var
global d_var
global e_var
global f_var

a_var = IntVar()
a_var = 1

b_var = IntVar()
b_var = 0

c_var = IntVar()
c_var = 1

d_var = IntVar()
d_var = 0

e_var = IntVar()
e_var = 0

f_var = IntVar()
f_var = 0

#####
#####Checkbutton Functions
#####

#If cb_a and cb_b are both deselected at the same time then print("Error!")
def cb_a_update():
    global a_var
    global b_var
    
    if a_var == 1:
        if b_var == 1:
            a_var = 0 
            cb_a.a_var = a_var
            print("cb_a is deselected and cb_b is selected.")
        else:
            a_var = 0 
            cb_a.a_var = a_var
            print("Error! cb_a and cb_b are both deselected!")
    else:
        a_var = 1
        cb_a.a_var = a_var
        print('cb_a is selected.')

#If cb_a and cb_b are both deselected at the same time then print("Error")
def cb_b_update():
    global a_var
    global b_var
    
    if b_var == 1:
        if a_var == 1:
            b_var = 0 
            cb_b.b_var = b_var
            print("cb_b is deselected and cb_a is selected.")
        else:
            b_var = 0 
            cb_b.b_var = b_var
            print("Error! cb_b and cb_a are both deselected!")
    else:
        b_var = 1
        cb_b.b_var = b_var
        print('cb_b is selected.')

#For these 4 Checkbuttons, only 1 can be selected at any given time.
def cb_c_update():
    global c_var
    global d_var
    global e_var
    global f_var
    
    if c_var == 1:
        print("cb_c should not be allowed to deselect manually - should not see this message")
    else:
        c_var = 1
        cb_c.c_var = c_var
        cb_c.configure(state=DISABLED)
        d_var = 0
        cb_d.d_var = d_var
        cb_d.configure(state=ACTIVE)
        e_var = 0
        cb_e.e_var = e_var
        cb_e.configure(state=ACTIVE)
        f_var = 0
        cb_f.f_var = f_var
        cb_f.configure(state=ACTIVE)
        print("cb_c was selected/disabled and cb_d,e,f are deselected/active")

def cb_d_update():
    global c_var
    global d_var
    global e_var
    global f_var
    
    if d_var == 1:
        print("cb_d should not be allowed to deselect manually - should not see this message")
    else:
        d_var = 1
        cb_d.d_var = d_var
        cb_d.configure(state=DISABLED)
        c_var = 0
        cb_c.c_var = c_var
        cb_c.configure(state=ACTIVE)
        e_var = 0
        cb_e.e_var = e_var
        cb_e.configure(state=ACTIVE)
        f_var = 0
        cb_f.f_var = f_var
        cb_f.configure(state=ACTIVE)
        print("cb_d was selected/disabled and cb_c,e,f are deselected/active")

def cb_e_update():
    global c_var
    global d_var
    global e_var
    global f_var
    
    if e_var == 1:
        print("cb_e should not be allowed to deselect manually - should not see this message")
    else:
        e_var = 1
        cb_e.e_var = e_var
        cb_e.configure(state=DISABLED)
        c_var = 0
        cb_c.c_var = c_var
        cb_c.configure(state=ACTIVE)
        d_var = 0
        cb_d.d_var = d_var
        cb_d.configure(state=ACTIVE)
        f_var = 0
        cb_f.f_var = f_var
        cb_f.configure(state=ACTIVE)
        print("cb_e was selected/disabled and cb_c,d,f are deselected/active")

def cb_f_update():
    global c_var
    global d_var
    global e_var
    global f_var
    
    if f_var == 1:
        print("cb_f should not be allowed to deselect manually - should not see this message")
    else:
        f_var = 1
        cb_f.f_var = f_var
        cb_f.configure(state=DISABLED)
        c_var = 0
        cb_c.c_var = c_var
        cb_c.configure(state=ACTIVE)
        d_var = 0
        cb_d.d_var = d_var
        cb_d.configure(state=ACTIVE)
        e_var = 0
        cb_e.e_var = e_var
        cb_e.configure(state=ACTIVE)
        print("cb_f was selected/disabled and cb_c,d,e are deselected/active")

#####
#####Define Checkbuttons
#####
cb_a = Checkbutton(root, text="A",variable=a_var,onvalue=1,offvalue=0,command=cb_a_update)
cb_b = Checkbutton(root, text="B",variable=b_var,onvalue=1,offvalue=0,command=cb_b_update)

cb_c = Checkbutton(root, text="C",variable=c_var,onvalue=1,offvalue=0,command=cb_c_update,state=DISABLED)
cb_d = Checkbutton(root, text="D",variable=d_var,onvalue=1,offvalue=0,command=cb_d_update)
cb_e = Checkbutton(root, text="E",variable=e_var,onvalue=1,offvalue=0,command=cb_e_update)
cb_f = Checkbutton(root, text="F",variable=f_var,onvalue=1,offvalue=0,command=cb_f_update)

#####
#####Place Checkbuttons on grid layout
#####
cb_a.grid(row=0,column=0)
cb_a.select()
cb_b.grid(row=0,column=1)
cb_b.deselect()

cb_c.grid(row=1,column=0)
cb_c.select()
cb_d.grid(row=1,column=1)
cb_d.deselect()
cb_e.grid(row=1,column=2)
cb_e.deselect()
cb_f.grid(row=1,column=3)
cb_f.deselect()

root.mainloop()



Aucun commentaire:

Enregistrer un commentaire