I work at an addon that works with external icons. When I run the script from within Blender then all is fine. When I make it an add-on, and install it, and try to activate it, then I get an error:
AttributeError: '_RestrictContext' object has no attribute 'space_data'
The vital code part that throws the error is:
script_path = bpy.context.space_data.text.filepath
Why does it work when i run it inside Blender, and not as an addon?
The problem reduced to one icon button:
import bpy
import os
import bpy.utils.previews
bl_info = {
"name": "Icon problem as addon",
"author": "X",
"version": (1, 0, 0),
"blender": (2, 76, 0),
"location": "",
"description": "Test",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "User Interface"}
# ¸¸♫·¯·♪¸¸♩·¯·♬¸¸¸¸♫·¯·♪¸¸♩·¯·♬¸¸¸¸♫·¯·♪¸¸♩·¯·♬¸¸¸¸♫·¯·♪¸¸♩·¯·♬¸¸¸¸♫·¯·♪¸¸♩·¯·♬¸¸¸¸♫·¯·♪¸¸♩·¯·♬¸¸
def addon_button(self, context):
layout = self.layout
global custom_icons
row = layout.row(align=True)
row.operator("object.mode_set", text="", icon_value = custom_icons["icon_not_available"].icon_id).mode = 'OBJECT'
# global variable to store icons in
custom_icons = None
def register():
bpy.types.VIEW3D_HT_header.prepend(addon_button) # Here we add our button in front of the View 3D header.
# Our external Icons
global custom_icons
custom_icons = bpy.utils.previews.new()
script_path = bpy.context.space_data.text.filepath
icons_dir = os.path.join(os.path.dirname(script_path), "icons")
custom_icons.load("icon_not_available", os.path.join(icons_dir, "NOT_AVAILABLE.png"), 'IMAGE')
def unregister():
global custom_icons
bpy.utils.previews.remove(custom_icons)
# This allows you to run the script directly from blenders text editor
# to test the addon without having to install it.
if __name__ == "__main__":
register()
script_path = bpy.context.space_data.text.filepath
in an addon anyhow? For an addon consider usingicon_dir = path.join(path.dirname(__file__), "icons")
(path is os.path) $\endgroup$