I have the same problem. I create global variable and then access it from two different classes: button changes it +1, panel draws it. However, while panel can always draw it, button CAN NOT change it - and yes, I used the global keyword inside the button class.
After some digging, my answer is: Blender can not create Python's global variables directly in a script.
My explanation of "Why?" comes from understanding of Blender internals:
- Blender developers decided that everything should go through Blender's API
- If everything goes through Blender's API, Blender can save it to a .blend file, which makes user happy
- If something goes around or works outside of Blender API, it can't be saved in .blend file (the Blender simply does not know about it) and some users would surely cry
- Blender's Script is always executed (for any action) whole again - thus our wanna-be global variable is created, changed, forgotten, created, changed, forgotten, etc.
Consider this example:
my_var = 1
def my_func():
global my_var
my_var = 2
print(my_var)
my_func()
print(my_var)
On Windows with Python 3.4, its double run leads to
C:\Python34\python test.py
1
2
C:\Python34\python test.py
1
2
As expected, python enviroment was terminated after first run and all its context was forgotten. When run be second time, Windows allocated new memory for the Python, where the code was executed again as new.
However, one would expect in Blender, whose thread/process is still running that such global variable would be remembered. IT IS NOT. Its double run using Text>Run Script or Alt+P twice in Blender's Text Editor mode leads to
1
2
1
2
instead of expected
1
2
2
3
While I do understand the need to save everything properly into .blend file, I do not agree with the Blender's policy: Use my API or Die. I am writing GPLed CAD for Blender and I will use my own portable HDF5 file to store scientific data properly. Blender is used only for visualisation and volume definition. So it does not need to and should not depend on .blend file at all (remember, portability). I want use python's global variables for my UI, but I can't.
Three workarounds are possible:
- Use Blender's types from bpy module
- Write another module with a python's global variable in it and import it into your script.
- Save your variable into file and load it
Hopefully, the Blender Developers will change their mind in future and will allow classic global variables in one script. Until then, I recommend the second option - import your another module with global variable in it. Just for completeness, the first crazy-for-beginner option may look like
bpy.types.Material.my_float = bpy.props.FloatProperty(name="unique-name-of-my-float")
The second option with new python module named my_module.py with single line
my_variable = 1
can be used in your original script as
import my_module
def my_func():
my_module.my_var = 2
where the my_var will be remembered during whole Blender session and finally the third, little-extreme but always-working option is
f = open("C:\my_global_variable.txt", 'r')
my_global_variable = int(f.readline())
f.close()