Help with python functions

2

I made a code that uses some functions. Such functions give a value to n and as they are called, the value of n changes (these functions are at the beginning of the code). What happens is that when you execute the script, so do not call the functions they all run and give a final value to n as if you had called them all and never called them What happens?

my Main Application

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
        self.nfont = tkfont.Font(family="Helvetica", size=15, slant="italic")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (StartPage, Page1):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")
        def p1():

            global n
            n = 1
            print ("Probando")

My Page 1

class Page1(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.configure(bg="black")
        # Declaramos y llamamos la tabla
        x = 1

        tabla = PhotoImage( file="tabla00.PNG")
        labeltabla = Label(self, image=tabla)
        labeltabla.image = tabla
        labeltabla.pack()

        label = tk.Label(self, bg="black", fg= "white", text="¿Tu número se encuentra en esa tabla?", font=controller.title_font)
        label.pack()

        si = tk.Button(self, text="Sí", command=SampleApp.p1(), width=10, height=2, relief="raised", borderwidth=5)
        no = tk.Button(self, text="No", width=10, height=2, relief="raised", borderwidth=5)
        pasar = tk.Button(self, text="Pasar a la siguiente página", width=20, height=3, relief="raised", borderwidth=5, command=lambda: controller.show_frame("Page2"))
        si.pack()
        no.pack()
        pasar.pack()

My application start

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        # Definimos funciones básicas de la ventana
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.configure(bg="black")
        # Creamos y damos caracteristicas a los frames
        titulo = tk.Label(self, bg="black", text="Bienvenidos...", fg= "white", font=controller.title_font)
        instrucciones = tk.Label(self, bg="black", fg= "white", text="Instrucciones:", font=controller.title_font)
        label = tk.Label(self, bg="black", fg= "white" , text="\nEste es un pequeño juego matemático que consiste en que tú piensas un número \nentre el 1 al 1023, y yo adivino cuál es.", font=controller.nfont)
        label2 = tk.Label(self, bg="black", fg= "white", text="\nVas a pensar en un número antes de empezar. Al momento de que le des al botón, \nsaldrá una imagen con muuuchos números. No te asustes, los números están en orden. \nEs decir que si piensas en el 108, este debe estar entre el 107 y el 109 o lo que más se acerca.", font=controller.nfont)
        # Empaquetamos los labels
        titulo.grid(row=0)
        label.grid(row=1)
        instrucciones.grid(row=2, pady=20)
        label2.grid(row=3, padx=30)
        # Boton
        button1 = tk.Button(self, text="Empezar",
                            command=lambda: controller.show_frame("Page1"), width=20, height=5, relief="raised", borderwidth=5)
        button1.grid(row=4, pady=50)
    
asked by Nicolás Arévalo 06.11.2018 в 04:37
source

1 answer

2

In view of the code that the user puts as part of the question, which contains things of this style:

class SampleApp(tk.Tk):

    def p1():    
        global n
        n = 1
        print ("Probando")

It is clear that if the chain "Probando" appears when launching the program, it is that the function p1() has been executed at some point even if it says no.

Since finally the user in a comment provides the complete code in a link to this pastebin (and from which subsequently @JackNavaRow , very kindly added the relevant fragments to the question), I have been able to detect the point where they are called functions.

For example, as part of the code (which I do not reproduce completely because it is very long), this constructor appears in another class:

class Page1(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.configure(bg="black")
        # Declaramos y llamamos la tabla
        x = 1

        tabla = PhotoImage( file="tabla00.PNG")
        labeltabla = Label(self, image=tabla)
        labeltabla.image = tabla
        labeltabla.pack()

        label = tk.Label(self, bg="black", fg= "white", text="¿Tu número se encuentra en esa tabla?", font=controller.title_font)
        label.pack()

        si = tk.Button(self, text="Sí", command=SampleApp.p1(), width=10, height=2, relief="raised", borderwidth=5)
        no = tk.Button(self, text="No", width=10, height=2, relief="raised", borderwidth=5)
        pasar = tk.Button(self, text="Pasar a la siguiente página", width=20, height=3, relief="raised", borderwidth=5, command=lambda: controller.show_frame("Page2"))
        si.pack()
        no.pack()
        pasar.pack()

And there we can see the call, on the line created by the si button:

    si = tk.Button(self, text="Sí", command=SampleApp.p1(), width=10, height=2, relief="raised", borderwidth=5)

Your fault is that instead of providing the reference to the function to execute, which would be SampleApp.p1 , you called that function and you provide the returned value. It should have been like this:

    si = tk.Button(self, text="Sí", command=SampleApp.p1, width=10, height=2, relief="raised", borderwidth=5)

And like this, you have many other button creations that also invoke their command function instead of passing a reference to them.

Clarification . For completing the analysis of the problem, the class that represents the entry point of the application, in its constructor, iterates through the rest of the classes and creates the frames by instantiating all those classes.

Each one of those classes, when instantiated, executes its constructor, and within all those constructors a si button is created which is tried to assign as command each of the functions SampleApp.p1 , SampleApp.p2 , SampleApp.p3 , etc ... But in all cases the same error mentioned above is being made, so that these functions, instead of being merely referenced, are executed.

Therefore, when loading the main class, you end up executing all those functions through the constructors of the rest of the classes that are instantiated.

    
answered by 06.11.2018 / 21:17
source