Blender code for set Folder directory path

Hello,

I am a programmer but not with python,

I have an addon that imports assets from a folder, the folder path is in the same directory, and what I want is to be able to change a custom directory in the addon preference panel,

I am using this code but I got nothing in the addon panel:

import bpy
from bpy.types import AddonPreferences
from bpy.props import StringProperty

class MyAddonPreferences(AddonPreferences):
    bl_idname = __name__

    folder_path: StringProperty(
        name="Folder Path",
        subtype='DIR_PATH',
        default="",
        description="Choose a directory for your addon"
    )

    def draw(self, context):
        layout = self.layout
        layout.prop(self, "folder_path")

def register():
    bpy.utils.register_class(MyAddonPreferences)

def unregister():
    bpy.utils.unregister_class(MyAddonPreferences)

if __name__ == "__main__":
    register()

I would really apperciate any help :frowning:

You need to include the bl_info dictionary.

Add-on Tutorial — Blender Manual

What is an Add-on?

An add-on is simply a Python module with some additional requirements so Blender can display it in a list with useful information.

To give an example, here is the simplest possible add-on:

bl_info = {
    "name": "My Test Add-on",
    "blender": (2, 80, 0),
    "category": "Object",
}
def register():
    print("Hello World")
def unregister():
    print("Goodbye World")

bl_info

is a dictionary containing add-on metadata such as the title, version and author to be displayed in the Preferences add-on list. It also specifies the minimum Blender version required to run the script; older versions won’t display the add-on in the list.

bl_info = {
    "name": "Test",
    "author": "Nezumi",
    "version": (0, 0, 0),
    "blender": (3, 6, 1),
    "location": "Search",
    "description": "None",
    "warning": "None",
    "wiki_url": "None",
    "category": "File",
}


import bpy
from bpy.types import AddonPreferences
from bpy.props import StringProperty

class MyAddonPreferences(AddonPreferences):
    bl_idname = __name__

    folder_path: StringProperty(
        name="Folder Path",
        subtype='DIR_PATH',
        default="",
        description="Choose a directory for your addon"
    )

    def draw(self, context):
        layout = self.layout
        layout.prop(self, "folder_path")

def register():
    bpy.utils.register_class(MyAddonPreferences)

def unregister():
    bpy.utils.unregister_class(MyAddonPreferences)

if __name__ == "__main__":
    register()

prefs_red

Thank you for helping :) 


I have this code in the addon: 

#Preferences UI

import bpy
import os
import zipfile
import bpy_extras

   

class smwish_SimpleOperator(bpy.types.Operator):
    bl_idname = "object.simple_operator"
    bl_label = "Open Assets Library Path"
    
    def execute(self, context):
        # Get the path of the current __init__ file
        addon_path = os.path.dirname(__file__)
        assets_path = os.path.join(addon_path, "Assets")
        
        # Check if directory exists
        if not os.path.exists(assets_path):
            self.report({'ERROR'}, "Assets directory does not exist!")
            return {'CANCELLED'}
        
        # Open the directory
        if os.name == 'nt':  # Windows
            os.startfile(assets_path)
        elif os.name == 'posix':  # MacOS and Linux
            os.system(f'xdg-open "{assets_path}"')
        else:
            self.report({'ERROR'}, "Unsupported OS!")
            return {'CANCELLED'}
        
        return {'FINISHED'}

class smwish_ImportZIP(bpy.types.Operator, bpy_extras.io_utils.ImportHelper):
    bl_idname = "object.import_zip"
    bl_label = "Import ZIP to Assets Library"
    filename_ext = ".zip"
    
    def execute(self, context):
        addon_path = os.path.dirname(__file__)
        assets_path = os.path.join(addon_path, "Assets")
        with zipfile.ZipFile(self.filepath, 'r') as zip_ref:
            # Count files for progress
            total_files = len(zip_ref.namelist())
            
            # Start the progress bar
            bpy.context.window_manager.progress_begin(0, 100)
            
            for i, file in enumerate(zip_ref.namelist()):
                zip_ref.extract(file, assets_path)
                
                # Update progress
                progress = (i / total_files) * 100
                bpy.context.window_manager.progress_update(progress)

            # End the progress bar
            bpy.context.window_manager.progress_end()

        bpy.ops.swsh.reload_assets()
        self.report({'INFO'}, "Files extracted successfully!")
        return {'FINISHED'}


class smwish_SimpleAddonPreferences(bpy.types.AddonPreferences):
    bl_idname = __package__
    
    def draw(self, context):
        layout = self.layout
        layout.label(text="Install assets pack to assets library:")

        #text Please be patient when installing the Assets Pack. Please refrain from performing any actions until the import is completed as indicated.
        layout.label(text="Please be patient when installing the Assets Pack. ", icon='INFO')



        layout.operator("object.import_zip", text="Import ZIP to Assets Library", icon='IMPORT')

        #row
        row = layout.row()

        layout.operator("object.simple_operator", text="Open Assets Library Path", icon='FILE_FOLDER')


which unzip files and open the assets folder, and what I want is to stop both of them and instead having a manual folder choosing,

I tried to do your code, but i think it get some problems with the corrent code

these are the reg and unreg

def register():
    bpy.utils.register_class(smwish_SimpleOperator)
    bpy.utils.register_class(smwish_ImportZIP)
    bpy.utils.register_class(smwish_SimpleAddonPreferences)

def unregister():
 #Preferences
    bpy.utils.unregister_class(smwish_SimpleOperator)
    bpy.utils.unregister_class(smwish_ImportZIP)
    bpy.utils.unregister_class(smwish_SimpleAddonPreferences)

Make note, this is no to be the old method is it not. From 4.2 and using the extension approach, it’s a side file and different method

Do you pass the custom folder path to the other operators?

You need to add a variable to the operator which check if the custom path is set and then retrieve it. Than use that path in the execution.

In your operators your calling for the path of the addon it self