1

I have a Tkinter application, so I have the mainloop which is typical of Tkinter, and various functions which handle mouse clicks and all that garbage.

In one of the functions, I generate a string and I want to store that string SOMEWHERE in the program, so that I can use it later on if some other function is called or maybe if I want to print it from the main loop.

import this and that, from here and there etc etc
#blah blah global declarations


fruit = ''
def somefunction(event):
    blahblahblah; 

    fruit = 'apples'
    return fruit
mainwin = Tk()


#blah blah blah tkinter junk
#my code is here
#its super long so I don't want to upload it all
#all of this works, no errors or problems
#however
button = Button( blahblahblha)
button.bind("<button-1", somefunction)

print fruit

#yields nothing

mainwin.mainloop()

This is an abridged example. Everything else in the program works fine, I can track my variable throughout the program, but when it's time for it to be saved for later use, it gets erased.

For example, I can print the variable as I pass it along from one function to another as an argument, and it will be fine. It is always preserved, and prints. The instant I try to get it back into the loop or store it for later use, it gets lost or overwritten (I'm not quite sure which).

I am really unfamiliar with Python, so I bet it's something simple that I've missed. I am assuming this is supposed to work like every other language, where you save a string to a global variable, and it will stay there UNTIL you or something resets it or overwrites it.

My current workaround is to create a text file and save the string in it until I need it.

I am using Python 2.7.11 on Windows 7, but have had the same issue on Ubuntu.

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
ernastovich
  • 15
  • 1
  • 5
  • That's a pretty long question. Brevity would have helped better. See whether this Q/A helps http://stackoverflow.com/questions/19980907/global-variable-issues-with-tkinter-python – chanux Jan 16 '16 at 03:35

3 Answers3

1

When you do fruit = 'anything' inside the function, it assigns it as a local variable. When the function ends, that local variable disappears. If you want to reassign to a global variable, you need to indicate that you'd like to do so with the global keyword.

def somefunction(event):
    global fruit # add this
    blahblahblah
    fruit = 'apples'
    return fruit

Note that functions can access global variables without this line, but if you want an assignment to the same name to apply to the global one you have to include it.

Also, "<button-1" should be "<button-1>".

Also, instead of binding to a Button, you should just add a command to it:

button = Button(mainwin, text='blahblah', command=somefunction)

And Button widgets, when clicked, don't send an event object to the function they're bound to, so define somefunction as def somefunction():.

Also, the print fruit is executed exactly once. If you want to change fruit and then see the new value, you'll have to print it as some point after you've done the reassignment. Using return to send a value to a Button doesn't do anything, as the widget can't do anything with it. This is why Tkinter apps are commonly created as object-oriented (OO) programs, so you can easily save instance variables without having to use global.

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • TigerhawkT3 thank you for the fantastic answer, it worked! Thanks for the answer and the suggestions if we were at a bar i'd buy a beer, or some chocolate milk or something this has literally shaved off nearly 30 lines of code opening and closing files. – ernastovich Jan 16 '16 at 03:45
0

Learn classes and your problems disappear. Almost any of these cover classes https://wiki.python.org/moin/BeginnersGuide/Programmers Also a Tkinter reference so you can fix your typos http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm

import sys

if sys.version_info[0] < 3:
    import Tkinter as tk     ## Python 2.x
else:
    import tkinter as tk     ## Python 3.x

class StoreVariable():
    def __init__(self, root):
        self.fruit = ''
        button = tk.Button(root, bg="lightblue")
        button.grid()
        button.bind("<Button-1>", self.somefunction)

        tk.Button(root, text="Exit", bg="orange", command=root.quit).grid(row=1)

    def print_fruit(self):
        print self.fruit

    def somefunction(self, event):
        self.fruit = 'apples'
        print "fruit changed"


mainwin = tk.Tk()
SV=StoreVariable(mainwin)
mainwin.mainloop()

## assume that once Tkinter exits there is something stored
## note that you have exited Tkinter but the class instance still exists
print SV.fruit
## call the class's built in function
SV.print_fruit()
  • Thank you! Classes have been a weak point for me for some time now honestly. It isn't just python, I just avoid classes like the plague because I haven't really seen their purpose. Everytime i had tried to use it, it ended up complicating the code. (can you tell I am not an avid programmer? *laughs in parentheses*) – ernastovich Jan 16 '16 at 03:51
0

Basing on your abridged function, here are some things that might caused your problems:

  • You might not saved fruit to a variable inside the main loop/program. Values saved inside a function will be erased once that function finishes. Unless you saved it inside a class variable using self.variable_name (applicable if you are using classes). If you don't like classes, just save it within a variable inside the main loop/function like:

    fruit = somefunction()

    other stuff

    print fruit #the time where you access fruit again

where this statement is inside the main loop/program where you would accesss it again with print.

  • You might be changing the value of fruit with other statements/functions. Not definite since you haven't posted your whole code.
angbargas
  • 54
  • 6