I want my shader nodes to apply to an object when I click the image inside Enum

enter image description here

I am using the Enum template

# This sample script demonstrates a dynamic EnumProperty with custom icons.
# The EnumProperty is populated dynamically with thumbnails of the contents of
# a chosen directory in 'enum_previews_from_directory_items'.
# Then, the same enum is displayed with different interfaces. Note that the
# generated icon previews do not have Blender IDs, which means that they can
# not be used with UILayout templates that require IDs,
# such as template_list and template_ID_preview.
# Other use cases:
# - make a fixed list of enum_items instead of calculating them in a function
# - generate isolated thumbnails to use as custom icons in buttons
#   and menu items
# For custom icons, see the template "ui_previews_custom_icon.py".
# For distributable scripts, it is recommended to place the icons inside the
# script directory and access it relative to the py script file for portability:
#    os.path.join(os.path.dirname(__file__), "images")

import os
import bpy

def enum_previews_from_directory_items(self, context):
    """EnumProperty callback"""
    enum_items = []

    if context is None:
        return enum_items

    wm = context.window_manager
    directory = wm.my_previews_dir

    # Get the preview collection (defined in register func).
    pcoll = preview_collections["main"]

    if directory == pcoll.my_previews_dir:
        return pcoll.my_previews

    print("Scanning directory: %s" % directory)

    if directory and os.path.exists(directory):
        # Scan the directory for png files
        image_paths = []
        for fn in os.listdir(directory):
            if fn.lower().endswith(".jpg"):

        for i, name in enumerate(image_paths):
            # generates a thumbnail preview for a file.
            filepath = os.path.join(directory, name)
            icon = pcoll.get(name)
            if not icon:
                thumb = pcoll.load(name, filepath, 'IMAGE')
                thumb = pcoll[name]
            enum_items.append((name, name, "", thumb.icon_id, i))

    pcoll.my_previews = enum_items
    pcoll.my_previews_dir = directory
    return pcoll.my_previews

class PreviewsExamplePanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Previews Example Panel"
    bl_idname = "OBJECT_PT_previews"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

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

        row = layout.row()
        row.prop(wm, "my_previews_dir")

        row = layout.row()
        row.template_icon_view(wm, "my_previews")

        row = layout.row()
        row.prop(wm, "my_previews")

# We can store multiple preview collections here,
# however in this example we only store "main"
preview_collections = {}

def register():
    from bpy.types import WindowManager
    from bpy.props import (

    WindowManager.my_previews_dir = StringProperty(
        name="Folder Path",

    WindowManager.my_previews = EnumProperty(

    # Note that preview collections returned by bpy.utils.previews
    # are regular Python objects - you can use them to store custom data.
    # This is especially useful here, since:
    # - It avoids us regenerating the whole enum over and over.
    # - It can store enum_items' strings
    #   (remember you have to keep those strings somewhere in py,
    #   else they get freed and Blender references invalid memory!).
    import bpy.utils.previews
    pcoll = bpy.utils.previews.new()
    pcoll.my_previews_dir = ""
    pcoll.my_previews = ()

    preview_collections["main"] = pcoll


def unregister():
    from bpy.types import WindowManager

    del WindowManager.my_previews

    for pcoll in preview_collections.values():


if __name__ == "__main__":

When I click the image of the Enum, it will apply the materialenter image description here

I have write the script of the shader nodes operator but I am finding ways to apply it by enum

  • $\begingroup$ Not sure its required to parrot the template verbatim into your question. To clarify, is the idea to add your material as say the active material of the active object when the enum is selected. Suggest then that the enum be a property of the object type, not the window manager, and do changes via an update method of the enum property. See blender.stackexchange.com/questions/70710/… ... using your operator instead. $\endgroup$
    – batFINGER
    Apr 28 at 14:34
  • $\begingroup$ Sorry, I don't prefer that. I want to see an image in the enum so I can see the material preview in the enum. When I press on that image, it can add material to the selected object. That's what I mean. $\endgroup$
    – 8N Films
    Apr 29 at 3:25

Your Answer

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

Browse other questions tagged or ask your own question.