27
$\begingroup$

Is it possible to use different icons other than the default set and how?

$\endgroup$
1
  • 7
    $\begingroup$ +1 See TextEditor -> Templates -> Python -> UI Previews Custom Icon / Dynamic Enum $\endgroup$
    – zeffii
    Jun 12, 2015 at 9:40

1 Answer 1

40
$\begingroup$

Since 2.75 the python API allows for custom icons.

You can store custom icons and load them with bpy.utils.previews.ImagePreviewCollection class, which works like a dictionary.

First let's create such icon dictionary:

import bpy.utils.previews
icons_dict = bpy.utils.previews.new()

Next, we need to find path to our icons. Its best to put them inside a folder named 'icons' next to the script file:

import os
# this will work for addons 
icons_dir = os.path.join(os.path.dirname(__file__), "icons")
# but it won't give you usefull path when you opened a file in text editor and hit run.
# this will work in that case:
script_path = bpy.context.space_data.text.filepath
icons_dir = os.path.join(os.path.dirname(script_path), "icons")

Finally load icon.png into the dictionary. Blender uses 32x32 icons in UI:

icons_dict.load("custom_icon", os.path.join(icons_dir, "icon.png"), 'IMAGE')

Reference the icon by it's ID, use like this inside UI elements:

icon_value=icons_dict["custom_icon"].icon_id

It's best to handle loading of icons in the register function, clearing the icons in unregister function, and storing them in a global variable.

If enabled as an addon the filepath of __init__.py is the module variable __file__ in __init__.py and as shown can be converted to a directory path using os.path.dirname(__file__) to get the path to my_addon

Make an add-on with multiple python files to keep our addon's icons neatly contained in our addon's folder.

my_addon/
    __init__.py
    icons/
        icon.png

To test when running from text editor can add an icons folder to some known path, for example the Desktop folder

Desktop/
    icons/
        icon.png 

and change the code below accordingly to be its absolute path (in this example case /home/user/Desktop/), or the saved path of the text file, or that of the blend file.

bl_info = {
    "name": "Custom Icon Test",
    "author": "Your Name Here",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "View3D > UI > Tools",
    "description": "Test custom icons",
    "warning": "",
    "doc_url": "",
    "category": "Testing",
}

import os
import bpy
import bpy.utils.previews

class CUSTOM_PT_myPanel(bpy.types.Panel):
    bl_label = "My Icon Panel"
    bl_idname = "OBJECT_PT_custom_panel"
    bl_space_type = "VIEW_3D"   
    bl_region_type = "UI"
    bl_category = "Tools"

    def draw(self, context):
        global custom_icons
        self.layout.label(text="Blender SE", icon_value=custom_icons["custom_icon"].icon_id)

# global variable to store icons in
custom_icons = None

def register():
    global custom_icons
    custom_icons = bpy.utils.previews.new()
    addon_path =  os.path.dirname(__file__)
    icons_dir = os.path.join(addon_path, "icons")
    
    custom_icons.load("custom_icon", os.path.join(icons_dir, "icon.png"), 'IMAGE')
    bpy.utils.register_class(CUSTOM_PT_myPanel)

def unregister():
    global custom_icons
    bpy.utils.previews.remove(custom_icons)
    bpy.utils.unregister_class(CUSTOM_PT_myPanel)

if __name__ == "__main__":
    # Test run
    # edit to folder containing your icons folder
    __file__ = "/home/user/Desktop/"
    # The path of this text (if saved)
    #__file__ = bpy.context.space_data.text.filepath
    # The path of this blend file (if saved)
    #__file__ = bpy.data.filepath
    register()

Result:

enter image description here

$\endgroup$
4
  • $\begingroup$ Sweet I have to try this out! $\endgroup$ Jan 25, 2016 at 23:54
  • $\begingroup$ Can you set the icon this way to an add-on that appears in a search menu? e.g. setting the bl_icon to a custom value. $\endgroup$ Feb 16, 2017 at 2:19
  • $\begingroup$ @Jerryno, sorry that I cannot comment. I want to ask what format of icon image is needed. I use blender2.78. My image format is .png, size 16X16. But it cannot show the icon. And I also tried the TextEditor -> Templates -> Python -> UI Previews Custom Icon / Dynamic Enum method, but it also does not work. Thanks. $\endgroup$
    – zzj
    May 27, 2017 at 2:32
  • $\begingroup$ in certain contexts, relative icon files may not work (blender.stackexchange.com/questions/179739/…) consider adding os.path.abspath() surrounding os.path.join(icons_dir, "icon.png") $\endgroup$ Jun 6, 2022 at 4:22

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.