30
$\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

44
$\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$
5
  • $\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
  • $\begingroup$ legit works! :D $\endgroup$ Mar 19 at 10:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .