I have a problem. Previously they helped me solve a problem with some functions; it was very helpful, i fixed that problem but i got to another one of course haha.
To give a value at the end of the application (questions of the app function) I need to give it a value n
from within the function, but it tells me that I have to define it. But if I define it when printing the value, it gives me the value I defined, as if it hadn't helped.
I have tried to make the variable global but it keeps saying that the variable is not defined.
This is the part of the code that shows the problem:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
# Lo que se hace aqui no es relevante
# para el problema
def p1():
global n
n = 1
def p2():
global n
n = n + 2
# Y así en varias funciones más
In general, using a global variable is not a good idea. At the end of this answer I will give you an alternative.
But if you want to use a global variable, the problem with your code is that there is no such variable!
When inside a function you put
global n
, you are basically telling python that if the function ever tries to change the value of a symbol calledn
, the interpreter should not create a local variable with that name (which is what it would do by default if it didn't you would have putglobal n
). Instead, he should use the global variable namedn
. But that variable does not exist in your code.Just add it. For example, before
class SampleApp
you putThat will already create the global variable, with an initial value of
0
. When declaring functionsglobal n
modify the value ofn
, they will modify that global variable.Note that it is not enough that the variable exists. In addition, the functions must declare it as global, otherwise when, for example , it
p1()
doesn=1
, a local variable would be created in that function that would not affect the global one (besides, the local variable is destroyed once the function ends).Alternative
Instead of global variables you can use object attributes. An attribute of an object is similar to a variable, but it belongs only to that object. They are used by typing
self.n
for example.However in your particular case, using this approach would force you to change quite a few things in the code. Each of the functions
p1()
,p2()
, etc. should declare a parameterself
to be able to act onself.n
, but that would change the way you then bind those methods to your GUI buttons, since the way you have it you docommand=SampleApp.p1
, for example, so you're treating them as class methods and not of object. Instead you should putcommand=controller.p1
and so on with all the others (since itcontroller
is the instance object of the classSampleApp
).I repeat that although this is more correct, in your case it may be more confusing since in view of your code it can be seen that you do not correctly understand the concepts of object-oriented programming.
Update
After additional user feedback, it appears that the problem was not only in the use of that global variable, but that when displaying that variable at the end of the program it appeared not to have changed its value.
The fact is that the variable is displayed in a label, which is part of a frame that is created when starting the program. The tag takes a copy of the value it
n
has at that moment, and since we are at the beginning its value is 0. Even if the value of is changed latern
, the tag continues to have its original value 0, until it is shown at the end of everything.The truth is that the structure of your code is a labyrinth... but without redoing everything, as you have it, the simplest thing will be to change what that label shows just before showing it. Although the frame is created at the beginning, it is not shown until the end, and since you have a specific method to show the frames, it may be there where you look if the frame to show is the last one and in that case you change the text to the label for the value it
n
has at that moment.This would be the new method
show_frame()
:As you can see, we check if it
page_name
is"LastPage"
, and then before showing that frame, we useframe.children
to access its "children" (the labels and buttons that compose it) and select the called child"resultado"
(which will be the label to show the value ofn
), and we change its text to the value itn
has at that moment.In the class
LastPage
, when you create that tag you must give it the name"resultado"
, for the above code to work. So: