Loading Icons Into Custom Addon So I am trying to load icons into a custom script and am having a series of issues. I initially wanted to try having a separate file that was icons.py that would supply a dictionary of the images however I was able to get it to work without separating it by putting it in the register however when the script is loaded as an add on it doesnt show the menu options. 

So when I run it from the script editor it works but now when I have it run as an add on. Is there something I need to do to make it load first so the rest of the script can run?

import bpy
import bmesh
from bpy.props import *
from math import pi, radians
import os
import bpy.utils.previews

#attempting to load custom icons
from .icons import load_icons
from .icons import clear_icons

class customMenu(bpy.types.Menu):
    bl_label = "CustomMenu"
    bl_idname = "customMenu"

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

        icons = load_icons()

        if bpy.context.object.mode == "EDIT":
            #print("EDIT MODE!")
            layout.operator("bevelandsharp1.objects", text = "Make SSharp", icon_value=custom_icons["MakeSharpE"].icon_id)
icon_value=custom_icons["Xslap"].icon_id)
            layout.separator()
            layout.menu(eMeshtools.bl_idname, icon_value=custom_icons["Frame"].icon_id  )

        else:
            #print("OBJECT/OTHER MODE!")
            #layout.operator("custom.icon", text = "CustomIcon", )
            layout.separator()
            layout.menu(Meshtools.bl_idname, icon_value=custom_icons["Diagonal"].icon_id)
            layout.separator()
            layout.menu(ImpSettings.bl_idname, icon_value=custom_icons["Frame"].icon_id)
            layout.separator()
            layout.menu(ButtonsVPSub.bl_idname, icon_value=custom_icons["Gui"].icon_id)
            layout.separator()

custom_icons = None

def register():

    global custom_icons
    custom_icons = bpy.utils.previews.new()
    script_path = bpy.context.space_data.text.filepath

    icons_dir = os.path.join(os.path.dirname(script_path), "icons")

    custom_icons.load("custom_icon", os.path.join(icons_dir, "icon.png"), 'IMAGE')
    custom_icons.load("CST", os.path.join(icons_dir, "HIconCST.jpg"), 'IMAGE')
    custom_icons.load("Frame", os.path.join(icons_dir, "HIconFrame.jpg"), 'IMAGE')
    custom_icons.load("Diagonal", os.path.join(icons_dir, "HIcondiagonal.jpg"), 'IMAGE')
....
Recently added a custom icons module to an addon... thought it might be an interesting answer to this q.  Code is basically the text editor custom icon template.

Icons stored in an icons folder inside the addon's folder.

import bpy

from os import path
icon_dir = path.join(path.dirname(__file__), "icons")
preview_collections = {}

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
    # load a preview thumbnail of a file and store in the previews collection
    icons = {"midi" : "midi.png",
            }
    for key, f in icons.items():
        pcoll.load(key, path.join(icon_dir, f), 'IMAGE')

    preview_collections["main"] = pcoll


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


Registered: icons.register() is called from my addons register method (in __init__.py ), after imp(ort)ing icons module.

Now in any other file, i can import the preview dictionary, then use in a draw method

    def draw_header(self, context):
        from sound_drivers.icons import preview_collections
        pcoll = preview_collections["main"]
        icon = pcoll["midi"]
        self.layout.label("", icon_value=icon.icon_id)


Note sound_drivers is the name of addon, change to suit.