2
$\begingroup$

I'm struggling with implementing a custom icons into script. As my level of Python is low, I did try others suggestions but without any luck. Addon never show up in Blender, but it's installed in blender addon folder.

Always tested with zip file, as zip file contain a script Selection.py and folder "icons" with init.py script inside.

I always get error - ImportError: No module named 'icons'.

I believe that I never register a init.py script and Selection.py script can't see it. ?

Scripts

Selection.py script

import bpy
import bpy.utils.previews
from icons import get_icon_id
from bpy.types import (
        Panel,
        Menu,
        Operator,
        )
from bpy.props import IntProperty, FloatProperty

bl_info = {
    "name": "IPG",
    "author": "InvisibleParrot",
    "version": (0, 0, 1),
    "blender": (2, 77, 0),
    "location": "View3D > Edit Mode",
    "description": "IPG tools of trade",
    "warning": "",
    "wiki_url": "",
    "category": "IPG Tools"}


class SelectionPanel(bpy.types.Panel):
    """Selection"""
    bl_label = 'Selection'
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = 'IPG Tools'

    def draw(self, context):
        layout = self.layout

        col = layout.column(align = True)

        col.operator("object.unwrapobject", text="Unwrap", icon_value=get_icon_id("C_Black"))


def register():
    bpy.utils.register_class(ColorSelectionPanel)

    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_class(ColorSelectionPanel)

    bpy.utils.unregister_module(__name__)


if __name__ == "__main__":
    register()

and init.py script

import os
import bpy

icons_collection = None
icons_directory = os.path.dirname(__file__)

def get_icon_id(identifier):
    # The initialize_icons_collection function needs to be called first.
    return get_icon(identifier).icon_id

def get_icon(identifier):
    if identifier in icons_collection:
        return icons_collection[identifier]
    return icons_collection.load(identifier, os.path.join(icons_directory, identifier + ".png"), "IMAGE")

def initialize_icons_collection():
    global icons_collection
    icons_collection = bpy.utils.previews.new()

def unload_icons():
    bpy.utils.previews.remove(icons_collection)

class IconsMock:
    def get(self, identifier):
        return get_icon(identifier)

icons = IconsMock()
$\endgroup$
  • $\begingroup$ from . import icons or from .icons import get_icon_id or from your_package.icons import get_icon_id or look at the 'importlib' especially import_module(...) which lets you use string names, and can take advantage of __package__ and __name__ $\endgroup$ – batFINGER Sep 4 '16 at 5:48
  • $\begingroup$ Do you know the custom icon example in the python api? blender.org/api/blender_python_api_2_76_release/… $\endgroup$ – Tiles Sep 4 '16 at 7:34
1
$\begingroup$

Thanks for response.

Ok, now everything works..

Is there cleaner way for doing this or I need always register new icon ?

import os
import bpy

bl_info = {
    "name": "IPG Selection",
    "author": "InvisibleParrot",
    "version": (0, 0, 1),
    "blender": (2, 77, 0),
    "location": "View3D > Edit Mode",
    "description": "IPG tools of trade",
    "warning": "",
    "wiki_url": "",
    "category": "IPG Tools"}


preview_collections = {}


class PreviewsExamplePanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = 'Selection'
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bl_category = 'IPG Tools'


    def draw(self, context):
        layout = self.layout

        col = layout.column(align = True)
        this_icon = preview_collections["custom_icons"]["custom_icon"].icon_id
        col.operator("render.render", text="Unwrap", icon_value=this_icon)
        this_icon = preview_collections["custom_icons"]["custom_icon2"].icon_id
        col.operator("render.render", text="Unwrap2", icon_value=this_icon)
        this_icon = preview_collections["custom_icons"]["custom_icon3"].icon_id
        col.operator("render.render", text="Unwrap3", icon_value=this_icon)
        this_icon = preview_collections["custom_icons"]["custom_icon4"].icon_id
        col.operator("render.render", text="Unwrap4", icon_value=this_icon)



def register():

    # Note that preview collections returned by bpy.utils.previews
    # are regular py objects - you can use them to store custom data.
    import bpy.utils.previews
    pcoll = bpy.utils.previews.new()

    # path to the folder where the icon is
    # the path is calculated relative to this py file inside the addon folder
    my_icons_dir = os.path.join(os.path.dirname(__file__), "icons")

    # load a preview thumbnail of a file and store in the previews collection
    pcoll.load("custom_icon", os.path.join(my_icons_dir, "C_Black.png"), 'IMAGE')
    pcoll.load("custom_icon2", os.path.join(my_icons_dir, "C_Blue.png"), 'IMAGE')
    pcoll.load("custom_icon3", os.path.join(my_icons_dir, "C_Yellow.png"), 'IMAGE')
    pcoll.load("custom_icon4", os.path.join(my_icons_dir, "C_Red.png"), 'IMAGE')

    preview_collections["custom_icons"] = pcoll

    bpy.utils.register_class(PreviewsExamplePanel)

    bpy.utils.register_module(__name__)



def unregister():

    for pcoll in preview_collections.values():
        bpy.utils.previews.remove(pcoll)
    preview_collections.clear()

    bpy.utils.unregister_class(PreviewsExamplePanel)

    bpy.utils.unregister_module(__name__)


if __name__ == "__main__":
    register()
| improve this answer | |
$\endgroup$
  • 2
    $\begingroup$ I preferred where you were going with this in the Q. You just needed to change how the previews were loaded and removed in icons.__init__.py and import it properly in Selection.py. (from . import icons) With this fixed you could simply call icons.initialize_icons_collection() in register, and unload in unregister. $\endgroup$ – batFINGER Sep 4 '16 at 11:51
0
$\begingroup$

I simply copied a part of my code, you can use your variables, this loads all the icons within your path:

def register()    
    iconcoll = bpy.utils.previews.new()
    preview_icon["icon"] = iconcoll

    icon_dir = os.path.join(###"Your path")   

    for ic in os.listdir(icon_dir):                
        iconcoll.load(ic, os.path.join(icon_dir,ic), 'IMAGE')
| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.