0

I'm a new programmer so sorry for any blunders. I'm creating the screens for an Italian quiz game. In LA COPERTINA screen, the buttons that should be used to increase or decrease the amount of money by 500 euros do not work and also 500 euros already appear while the tot1s variable is set to 0. What could be the error? add1 and add2 button call sottrai1 and aggiungi1 functions, but they don't work. I need to return tot1 cause it will update continuously during the game.

import tkinter as tk
from tkinter import *
from tkinter import ttk

from PIL import Image, ImageTk
from tkinter.font import Font

class schermoiniziale(tk.Frame):
    def __init__(self, master, **kw):
        # need to call __init__() of inherited class
        super().__init__(master, **kw)
        global g1, g2, g3, gio1, gio2, gio3, tot1, tot2, tot3, tot1s
        
        self.gio1=tk.StringVar()
        self.gio2=tk.StringVar()
        self.gio3=tk.StringVar()
        # stile per la formattazione del pulsante INIZIA
        style = ttk.Style()
        # configura lo sfondo della finestra che altrimenti sarebbe bianco
        self.configure(background="#000098")
        # definizione titolo e campi della finestra principale
        Titolo  = tk.Label(self, text="     SUPERFLASH     ", font="DS-Digital 100 bold italic", background='#000098', foreground='white')
        myLabel1 = tk.Label(self, text="Concorrente 1:", font="Arial 30 bold", background='#000098', foreground='white')
        myLabel2 = tk.Label(self, text="Concorrente 2:", font="Arial 30 bold", background='#000098', foreground='white')
        myLabel3 = tk.Label(self, text="Concorrente 3:", font="Arial 30 bold", background='#000098', foreground='white')
        self.g1 = tk.Entry(self, textvariable=self.gio1, font="Arial 20", width=50)
        self.g2 = tk.Entry(self, textvariable=self.gio2, font="Arial 20", width=50)
        self.g3 = tk.Entry(self, textvariable=self.gio3, font="Arial 20", width=50)
        Titolo.pack()
        myLabel1.pack(pady=2)
        self.g1.pack(pady=2)
        self.g1.focus()
        myLabel2.pack(pady=2)
        self.g2.pack(pady=2)
        myLabel3.pack(pady=2)
        self.g3.pack(pady=2)
        
        Inizio = ttk.Button(self, text="INIZIA", command=self.lacopertina, style="big.TButton")
        style.configure('big.TButton', font=(None, 20), foreground="black")
        Inizio.pack(padx=0, pady=10)
            
    def lacopertina(self):
        
        
        global tot1,tot1s    
        tot1s="0"
        tot1=0
        tot2=0
        tot3=0
        root2 = tk.Toplevel()
        nome1= self.gio1.get()
        nome2= self.gio2.get()
        nome3= self.gio3.get()
        self.tot1s=tk.StringVar()
        self.tot2s=tk.StringVar()
        # titolo finestra
        root2.title("LA COPERTINA")
        # finestra principale
        canvas1=Canvas(root2, width=1185, height=625, bg='#000098')
        canvas1.place(x=0, y=148)
        # finestra dei punteggi
        canvas2=Canvas(root2, width=300, height=573, bg='#000000')
        canvas2.place(x=1190, y=0)
        # finestra pulsante carte
        canvas4=Canvas(root2, width=300, height=200, bg='#01ebe8')
        canvas4.place(x=1190, y=573)
        # finestra immagine del titolo
        canvas3=Canvas(root2, width=1185, height=155)
        canvas3.place(x=0, y=0)
        load = Image.open("lacopertina.jpg")
        photo= ImageTk.PhotoImage(load)
        canvas3.create_image(593,74, image=photo)
        
        # etichette concorrenti
        NomeGiocatore1= tk.Label(canvas2, text="Giocatore1:", font=("Arial", 15),bg='#000', fg='#fff')
        NomeGiocatore1.place(x=20, y=20)
        NomeGiocatore2= tk.Label(canvas2, text="Giocatore2:", font=("Arial", 15),bg='#000', fg='#fff')
        NomeGiocatore2.place(x=20, y=200)
        NomeGiocatore3= tk.Label(canvas2, text="Giocatore3:", font=("Arial", 15),bg='#000', fg='#fff')
        NomeGiocatore3.place(x=20, y=380)
        # funzioni cambio ammontare
        def sottrai1(tot1):
            tot1=tot1-500
            #tot1s=str(tot1)
            myLabel41.config(text=tot1)
            return tot1
        def aggiungi1(tot1):
            tot1+=500
            #tot1s=str(tot1)
            myLabel41.config(text=tot1)
            return tot1
        
        
        # etichette con i nomi dei giocatori e ammontare in denaro
        myLabel4 = tk.Label(canvas2, text=nome1, font=("Arial", 15))
        myLabel4.place(x=20, y=60)
        myLabel40 = tk.Label(canvas2, text="€ ", font=("Arial", 15),bg='#000', fg='#e8f100')
        myLabel40.place(x=20, y=100)
        myLabel41 = tk.Label(canvas2, text=tot1s, font=("Arial", 15),bg='#000', fg='#e8f100')
        myLabel41.place(x=55, y=100)
        myLabel5 = tk.Label(canvas2, text=nome2, font=("Arial", 15))
        myLabel5.place(x=20, y=240)
        myLabel50 = tk.Label(canvas2, text="€ ", font=("Arial", 15),bg='#000', fg='#e8f100')
        myLabel50.place(x=20, y=280)
        myLabel51 = tk.Label(canvas2, text=tot2, font=("Arial", 15),bg='#000', fg='#e8f100')
        myLabel51.place(x=55, y=280)
        myLabel6 = tk.Label(canvas2, text=nome3, font=("Arial", 15))
        myLabel6.place(x=20, y=420)
        myLabel60 = tk.Label(canvas2, text="€ ", font=("Arial", 15),bg='#000', fg='#e8f100')
        myLabel60.place(x=20, y=460)
        myLabel61 = tk.Label(canvas2, text=tot3, font=("Arial", 15),bg='#000', fg='#e8f100')
        myLabel61.place(x=55, y=460)
        # pulsanti che modificano l'ammontare in denaro
        add1 = tk.Button(canvas2, text="-", command=sottrai1(tot1), font=("Arial", 10))
        add1.place(x=20, y=140)
        add2 = tk.Button(canvas2, text="+", command=aggiungi1(tot1), font=("Arial", 10))
        add2.place(x=50, y=140)
                
          
        root2.geometry("1500x783")
        root2.mainloop()
            
        
def main():
    # need to create the root window before creating other widget
    
    root = tk.Tk()
    
    root.title("SUPERFLASH")
    root.geometry("800x488")
    root.iconbitmap('icona.ico')
    
    #loadschermo1=Image.open("schermo2.jpg")
    #photoschermo1=ImageTk.PhotoImage(loadschermo1)
    #canvasschermo1.create_image(400,578, image=photoschermo1)

    
      
    # pass root window as the parent of the widget
    frame = schermoiniziale(root)
    frame.pack(padx=0, pady=0)
    
    # start the tkinter mainloop
    root.mainloop()

if __name__== "__main__":
    main()
  • Can you provide more specifics than "don't work"? What is supposed to happen, and why? What happens instead? What is the *first* thing that happens differently than you expected? – Scott Hunter Nov 30 '21 at 13:20
  • bye thank you. I try to re-explain, probably in the description it is not clear: MyLabel41 displays an amount that initially is equal to 0. The two buttons add1 and add2 call the functions sottrai1 and aggiungi1, they should respectively subtract and add 500 euros to the total in euros (in the tot1 variable). Not only do the buttons not subtract and add 500 euros but in canvas2 a total of 500 euros already appears which is not declared anywhere. It appears that the program performs both the sottrai1 and aggiungi2 functions without them being called by buttons. – James Garofalo Nov 30 '21 at 14:53

1 Answers1

1

It is a typical problem using tkinter when you associate a function/method to a button click, it is not intuitive.

You are giving command=sottrai1(tot1) as the add1 button action, right?.

Button wants a reference to a function, not the result of a function, as you are calling sottrai(tot1) it will be executed, evaluated and the result of it will be passed as a command for the button.

This is the problem, you see? You would like to execute the function every time, but in fact is executed only once at the beginning when you build your button.

Solutions:

  • To make it easy you can modify your sottrai1, remove the parameter and let it modify the global variable tot1, than instead of pass command=sottrai1(tot1) you will pass command=sottrai1 (the reference to the method, not the result of the method, understand?).
  • Use a python lambda (plenty of examples online and in official docs)
piertoni
  • 1,933
  • 1
  • 18
  • 30
  • Thank you very much. It's clear! I modified as you advised and now another error appears: tot1 + = 500 UnboundLocalError: local variable 'tot1' referenced before assignment – James Garofalo Nov 30 '21 at 15:00
  • inside the method only local variables are accessible and `tot1` is not defined. Try telling python interpreter that you want to use a variable which is non local. write `nonlocal tot1` just before using it, or in your case it's probably `global tot1` – piertoni Nov 30 '21 at 15:11
  • 1
    Thank you very much, now it's working :) – James Garofalo Nov 30 '21 at 15:23