All user-defined classes (panels, operators), registered in Blender API, exists only during Blender runs. After program close they are deleted from memory. Therefore, if some variables are defined in user classes, all of them will be reset after Blender restart.
However, sometimes it is necessary to use in Blender add-on variables with values that not be lost in the process of program restarting. To retain variables values, it needs to wrap them into special class – property, and attach to any object whose properties are stored in * .blend file.
Lets create a demo property-class SampleVariables, filled with a set of variables.
To convert user-defined class into complete property, it needs to inherit from bpy.types.PropertyGroup. For example define in our class two variables variable1 (numeric) and variable2 (boolean), which values must be preserved after Blender exit. Take the type of these two variables from bpy.props, so we can bring them on panel and easily change their values.
1 2 3 4 5 6 7 8 9 10 11 |
class SampleVariables(bpy.types.PropertyGroup): variable1 = bpy.props.IntProperty( name="Var1", description="Sample variable 1", default=2 ) variable2 = bpy.props.BoolProperty( name="Var2", description="Sample variable 2", default=True ) |
Like any user-defined class, to append our property class to the Blender API we must register it via the register_class and unregister at the end with unregister_class:
1 2 3 4 5 |
def register(): bpy.utils.register_class(SampleVariables) def unregister(): bpy.utils.unregister_class(SampleVariables) |
Also, lets create a panel SamplePanel, place it on the T-bar in Properties region, and createt layout whit our two variables in it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class SamplePanel(bpy.types.Panel): bl_idname = "panel.sample_panel" bl_label = "Panel for variable change" bl_space_type = "VIEW_3D" bl_region_type = "TOOL_PROPS" def draw(self, context): self.layout.prop(bpy.context.scene.sample_vars, 'variable1') self.layout.prop(bpy.context.scene.sample_vars, 'variable2') def register(): bpy.utils.register_class(SamplePanel) def unregister(): bpy.utils.unregister_class(SamplePanel) |
And, most importantly, property class must be appended as a property to one of the objects with structure stored in *.blend file. This may be any object that logically related these variables. In our example, variables are abstract and not tied to any specific objects, so make our class the whole scene property.
The binding must be done at the time of add-on registration:
1 2 |
def register(): bpy.types.Scene.sample_vars = bpy.props.PointerProperty(type=SampleVariables) |
and deleted with add-on unregistration:
1 2 |
def unregister(): del bpy.types.Scene.sample_vars |
We tied our property class SampleVars as the sample_vars scene property. Therefore, in our panel class layout we specified bpy.context.scene.sample_vars as the object to interact with property variables.
Full code of demo add-on that creates two variables, binds them as properties to the scene and places them on the T-bar to change their values:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
bl_info = { 'name': 'Saved Variables', 'category': 'All' } import bpy class SamplePanel(bpy.types.Panel): bl_idname = "panel.sample_panel" bl_label = "Panel for variable change" bl_space_type = "VIEW_3D" bl_region_type = "TOOL_PROPS" def draw(self, context): self.layout.prop(bpy.context.scene.sample_vars, 'variable1') self.layout.prop(bpy.context.scene.sample_vars, 'variable2') class SampleVariables(bpy.types.PropertyGroup): variable1 = bpy.props.IntProperty( name="Var1", description="Sample variable 1", default=2 ) variable2 = bpy.props.BoolProperty( name="Var2", description="Sample variable 2", default=True ) def register(): bpy.utils.register_class(SamplePanel) bpy.utils.register_class(SampleVariables) bpy.types.Scene.sample_vars = bpy.props.PointerProperty(type=SampleVariables) def unregister(): del bpy.types.Scene.sample_vars bpy.utils.unregister_class(SampleVariables) bpy.utils.unregister_class(SamplePanel) if __name__ == "__main__": register() |
Variables placed on the panel will keep the set values after Blender restarting.