Is it possible to use different icons other than the default set and how?
1 Answer
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:
-
$\begingroup$ Sweet I have to try this out! $\endgroup$ Commented 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$ Commented 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
, size16X16
. But it cannot show the icon. And I also tried theTextEditor -> Templates -> Python -> UI Previews Custom Icon / Dynamic Enum
method, but it also does not work. Thanks. $\endgroup$– zzjCommented 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()
surroundingos.path.join(icons_dir, "icon.png")
$\endgroup$ Commented Jun 6, 2022 at 4:22 -