Python Forum

Full Version: Python 3.8.1 Tkinter Widget stete change
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Dear Sirs,
This is my python code:
from tkinter import *

import math
import numpy as np

gui = Tk()
gui.title("Money Split")
gui.geometry("580x200")

v1 = IntVar()
v2 = IntVar()
v3 = IntVar()
v4 = IntVar()

def testVal(inStr,i,acttyp):
	ind=int(i)
	if acttyp == '1': #insert
		if not inStr[ind].isdigit():
			return False
	return True

R = 4
C = 3

valore = StringVar()

# Initialize np 
np = [[50, 0, 0], 
          [20, 0, 0],
	  [10, 0, 0],
	  [5, 0, 0]]
  
# For printing the np 
def shownp():
    for i in range(R): 
        for j in range(C): 
            print(np[i][j], end = " ") 
        print()

#create a callback for our button
def callback():
  global b50
  global a1
  
  if e0.get() != '':
    importo = int(e0.get())
    status_label['text'] = importo       
    if importo % 5 == 0 and importo >= 5:
      if v1.get():
        b50 = int(e1.get())
      else:
        if importo >= 50:
            b50 = math.ceil(importo / 85)
        else:
            b50=0
      np [0][2] = b50
      a1 = str(b50)
      e1.delete(0, END)
      e1.insert(0, a1)
        
      if v2.get(): 
        b20 = int(e2.get())
      else:
        if (importo - b50 * 50) >= 20:
            b20 = math.ceil((importo - b50 * 50) / 35)
        else:
            b20=0 
      np [1][2] = b20
      a2 = str(b20)
      e2.delete(0, END)
      e2.insert(0, a2)
        
      if v3.get():
        b10 = int(e3.get())
      else:
        if (importo - b50 * 50 - b20 * 20) >= 10:
            b10 = math.ceil((importo - b50 * 50 - b20 * 20) / 15)
        else:
            b10=0
      np [2][2] = b10
      a3 = str(b10)
      e3.delete(0, END)
      e3.insert(0, a3)
        
      if v4.get():
        b5 = int(e4.get())
      else:
        if (importo - b50 * 50 - b20 * 20 - b10 * 10) >= 5:
            b5 = math.ceil((importo - b50 * 50 - b20 * 20 - b10 * 10) / 5)
        else:
            b5 = 0    
      np [3][2] = b5
      a4 = str(b5)
      e4.delete(0, END)
      e4.insert(0, a4)

      print (b50 * 50 + b20 * 20 + b10 * 10 + b5 * 5)
      shownp()
      status_label['text'] = 'Done!'
      b1.state('normal')
      b2['state'] = 'normal'
      b3['state'] = 'normal'
      b4['state'] = 'normal'

    else:
      status_label['text'] = 'Insert a number divisible by 5'
      e0.delete(0,END)
      e1.delete(0,END)
      e2.delete(0,END)
      e3.delete(0,END)
      e4.delete(0,END)
      b1.configure(state='disabled')
      b2.configure(state='disabled')
      b3.configure(state='disabled')
      b4.configure(state='disabled')
      e0.focus

def change50(v1):
    print(v1)
    e1.delete(0,END)
    e2.delete(0,END)
    e3.delete(0,END)
    e4.delete(0,END)
    e1.insert(0, np [0][2] + v1)
    np [0][1] = 1
    callback()

def change20(v2):
    e1.delete(0,END)
    e2.delete(0,END)
    e3.delete(0,END)
    e4.delete(0,END)
    e2.insert(0, np [1][2] + v2)
    np [1][1] = 1
    callback()

def change10(v3):
    e1.delete(0,END)
    e2.delete(0,END)
    e3.delete(0,END)
    e4.delete(0,END)
    e3.insert(0, np [2][2] + v3)
    np [2][1] = 1
    callback()

def change5(v4):
    e1.delete(0,END)
    e2.delete(0,END)
    e3.delete(0,END)
    e4.delete(0,END)
    e3.insert(0, np [3][2] + v4)
    np [3][1] = 1
    callback()

def verifica(event=None):
    val1 = v1.get() * int(e1.get()) * 50
    val2 = v2.get() * int(e2.get()) * 20
    val3 = v3.get() * int(e3.get()) * 10
    val4 = v4.get() * int(e4.get()) * 5
    print (val1,val2,val3,val4)
    somma=val1+val2+val3+val4
    print (somma)
    valtot=int(e0.get())    
    if somma > valtot:
       b0.config(state = 'disabled')
       status_label['text'] = 'Change the fixed number of banknotes because it exceeds the amount to be split!'
    else:
       b0.config(state=NORMAL)
       
Label(gui, text="Importo").place(x=5, y=5, width=50)
Label(gui, text="50,00 €").place(x=5, y=35, width=50)
Label(gui, text="20,00 €").place(x=5, y=65, width=50)
Label(gui, text="10,00 €").place(x=5, y=95, width=50)
Label(gui, text="5,00 €").place(x=5, y=125, width=50)

a1 = StringVar()
a2 = StringVar()
a3 = StringVar()
a4 = StringVar()

e0 = Entry(gui, validate="key", justify='center')
e0['validatecommand'] = (e0.register(testVal),'%P','%i','%d')

e1 = Entry(gui, textvariable = a1, justify='center')
e2 = Entry(gui, textvariable = a2, justify='center')
e3 = Entry(gui, textvariable = a3, justify='center')
e4 = Entry(gui, textvariable = a4, justify='center')

#e0.grid(row=0, column=1)
e0.place(x=100, y=5, width=100)
e1.place(x=100, y=35, width=100)
e2.place(x=100, y=65, width=100)
e3.place(x=100, y=95, width=100)
e4.place(x=100, y=125, width=100)

b0 = Button(gui, text="Split", state='normal', command=callback).place(x=100, y=155, height=20, width=100)
b1 = Checkbutton(gui, text="fix", state='disabled', variable=v1, command=verifica).place(x=210, y=35, height=20, width=100)
b2 = Checkbutton(gui, text="fix", state='disabled',variable=v2, command=verifica).place(x=210, y=65, height=20, width=100)
b3 = Checkbutton(gui, text="fix", state='disabled',variable=v3, command=verifica).place(x=210, y=95, height=20, width=100)
b4 = Checkbutton(gui, text="fix", state='disabled',variable=v4, command=verifica).place(x=210, y=125, height=20, width=100)
b5 = Button(gui, text="Quit", command=gui.destroy).place(x=370, y=155, height=20, width=100)

status_label =Label(gui, height =3, width =35, bg ="black", fg ="#00FF00", text ="---", wraplength =200)
status_label.place(x=300, y=35, width=250)

e0.focus()

gui.mainloop()
I don't know why change button and checkbutton state is impossible for me.
I tried to use:

b1.state('normal')
b2['state'] = 'normal'
b0.config(state = 'disabled')
b0.config(state=NORMAL)


no one works! Angry
Why? Huh
Thanks for Your help
Best Regards
step one, please change all cryptic letter names to meaningful values.
Very hard to read without.
your entry statements either need embedded 'command' of external bind statements.
Thank You Larz60+!
I'm new in python.
You are right about the incomprehensibility of what I wrote.
I try to simplify:
from tkinter import *

import math
import numpy as np

# omissis...

def verifica(event=None):
    val1 = v1.get() * int(e1.get()) * 50
    val2 = v2.get() * int(e2.get()) * 20
    val3 = v3.get() * int(e3.get()) * 10
    val4 = v4.get() * int(e4.get()) * 5
    print (val1,val2,val3,val4)
    somma=val1+val2+val3+val4
    print (somma)
    valtot=int(e0.get())    
    if somma > valtot:
       b0.config(state = 'disabled') #<--- this doesn't work!!!
    else:
       b0.config(state=NORMAL) #<--- this doesn't work!!!


b0 = Button(gui, text="Split", state='normal', command=callback).place(x=100, y=155, height=20, width=100)
b1 = Checkbutton(gui, text="fix", state='disabled', variable=v1, command=verifica).place(x=210, y=35, height=20, width=100)
The problem lies in the fact that once the widgets (in this case b0 and b1) are set, I can no longer change their state (normal / disabled).
Have a nice day!
You need a reference to your Entries and CheckButtons.

CheckButton(...).place(...) return None.
To get the reference to the CheckButton, create first an instance of the object, assign it to a name and then you can use the method place, which return always None.
# instead of
b1 = CheckButton(...).place(...)

# do this
b1 = CheckButton(...)
b1.place(...)
Here your code, corrected imports, removed numpy, removed some globals, optimized imports and blacked.

import math
from tkinter import (
    Button,
    Checkbutton,
    IntVar,
    StringVar,
    Tk,
    Label,
    Entry,
    END,
    NORMAL,
)

gui = Tk()
gui.title("Money Split")
gui.geometry("580x200")

v1 = IntVar()
v2 = IntVar()
v3 = IntVar()
v4 = IntVar()


def test_val(in_str, i, act_type):
    ind = int(i)
    if act_type == "1":  # insert
        if not in_str[ind].isdigit():
            return False
    return True


R = 4
C = 3

valore = StringVar()

# Initialize np
np = [[50, 0, 0], [20, 0, 0], [10, 0, 0], [5, 0, 0]]


# For printing the np
def shownp():
    for i in range(R):
        for j in range(C):
            print(np[i][j], end=" ")
        print()


# create a callback for our button
def callback():
    global a1

    if e0.get() != "":
        importo = int(e0.get())
        status_label["text"] = importo
        if importo % 5 == 0 and importo >= 5:
            if v1.get():
                b50 = int(e1.get())
            else:
                if importo >= 50:
                    b50 = math.ceil(importo / 85)
                else:
                    b50 = 0
            np[0][2] = b50
            a1 = str(b50)
            e1.delete(0, END)
            e1.insert(0, a1)

            if v2.get():
                b20 = int(e2.get())
            else:
                if (importo - b50 * 50) >= 20:
                    b20 = math.ceil((importo - b50 * 50) / 35)
                else:
                    b20 = 0
            np[1][2] = b20
            a2 = str(b20)
            e2.delete(0, END)
            e2.insert(0, a2)

            if v3.get():
                b10 = int(e3.get())
            else:
                if (importo - b50 * 50 - b20 * 20) >= 10:
                    b10 = math.ceil((importo - b50 * 50 - b20 * 20) / 15)
                else:
                    b10 = 0
            np[2][2] = b10
            a3 = str(b10)
            e3.delete(0, END)
            e3.insert(0, a3)

            if v4.get():
                b5 = int(e4.get())
            else:
                if (importo - b50 * 50 - b20 * 20 - b10 * 10) >= 5:
                    b5 = math.ceil((importo - b50 * 50 - b20 * 20 - b10 * 10) / 5)
                else:
                    b5 = 0
            np[3][2] = b5
            a4 = str(b5)
            e4.delete(0, END)
            e4.insert(0, a4)

            print(b50 * 50 + b20 * 20 + b10 * 10 + b5 * 5)
            shownp()
            status_label["text"] = "Done!"
            b1.configure(state="normal")
            b2.configure(state="normal")
            b3.configure(state="normal")
            b4.configure(state="normal")

        else:
            status_label["text"] = "Insert a number divisible by 5"
            e0.delete(0, END)
            e1.delete(0, END)
            e2.delete(0, END)
            e3.delete(0, END)
            e4.delete(0, END)
            b1.configure(state="disabled")
            b2.configure(state="disabled")
            b3.configure(state="disabled")
            b4.configure(state="disabled")
            e0.focus()


def change50(v1):
    print(v1)
    e1.delete(0, END)
    e2.delete(0, END)
    e3.delete(0, END)
    e4.delete(0, END)
    e1.insert(0, np[0][2] + v1)
    np[0][1] = 1
    callback()


def change20(v2):
    e1.delete(0, END)
    e2.delete(0, END)
    e3.delete(0, END)
    e4.delete(0, END)
    e2.insert(0, np[1][2] + v2)
    np[1][1] = 1
    callback()


def change10(v3):
    e1.delete(0, END)
    e2.delete(0, END)
    e3.delete(0, END)
    e4.delete(0, END)
    e3.insert(0, np[2][2] + v3)
    np[2][1] = 1
    callback()


def change5(v4):
    e1.delete(0, END)
    e2.delete(0, END)
    e3.delete(0, END)
    e4.delete(0, END)
    e3.insert(0, np[3][2] + v4)
    np[3][1] = 1
    callback()


def verifica():
    val1 = v1.get() * int(e1.get()) * 50
    val2 = v2.get() * int(e2.get()) * 20
    val3 = v3.get() * int(e3.get()) * 10
    val4 = v4.get() * int(e4.get()) * 5
    print(val1, val2, val3, val4)
    somma = val1 + val2 + val3 + val4
    print(somma)
    valtot = int(e0.get())
    if somma > valtot:
        b0.config(state="disabled")
        status_label[
            "text"
        ] = "Change the fixed number of banknotes because it exceeds the amount to be split!"
    else:
        b0.config(state=NORMAL)


Label(gui, text="Importo").place(x=5, y=5, width=50)
Label(gui, text="50,00 €").place(x=5, y=35, width=50)
Label(gui, text="20,00 €").place(x=5, y=65, width=50)
Label(gui, text="10,00 €").place(x=5, y=95, width=50)
Label(gui, text="5,00 €").place(x=5, y=125, width=50)

a1 = StringVar()
a2 = StringVar()
a3 = StringVar()
a4 = StringVar()

e0 = Entry(gui, validate="key", justify="center")
# e0["validatecommand"] = (e0.register(testVal), "%P", "%i", "%d")

e1 = Entry(gui, textvariable=a1, justify="center")
e2 = Entry(gui, textvariable=a2, justify="center")
e3 = Entry(gui, textvariable=a3, justify="center")
e4 = Entry(gui, textvariable=a4, justify="center")

# e0.grid(row=0, column=1)
e0.place(x=100, y=5, width=100)
e1.place(x=100, y=35, width=100)
e2.place(x=100, y=65, width=100)
e3.place(x=100, y=95, width=100)
e4.place(x=100, y=125, width=100)

b0 = Button(gui, text="Split", state="normal", command=callback)
b1 = Checkbutton(gui, text="fix", state="disabled", variable=v1, command=verifica)
b2 = Checkbutton(gui, text="fix", state="disabled", variable=v2, command=verifica)
b3 = Checkbutton(gui, text="fix", state="disabled", variable=v3, command=verifica)
b4 = Checkbutton(gui, text="fix", state="disabled", variable=v4, command=verifica)
b5 = Button(gui, text="Quit", command=gui.destroy)

b0.place(x=100, y=155, height=20, width=100)
b1.place(x=210, y=35, height=20, width=100)
b2.place(x=210, y=65, height=20, width=100)
b3.place(x=210, y=95, height=20, width=100)
b4.place(x=210, y=125, height=20, width=100)
b5.place(x=370, y=155, height=20, width=100)

status_label = Label(
    gui, height=3, width=35, bg="black", fg="#00FF00", text="---", wraplength=200
)
status_label.place(x=300, y=35, width=250)

e0.focus()

gui.mainloop()
Hi
Fantastic optimized code!
Thank's, DeaD_EyE, for your help.
Best Regards