How to build an operator that corrects StringProperty("subtype = 'DIR_PATH') from relative path? I'm trying to build a &quot;smart&quot; operator, this has to transform a relative path (Cause of a lot of trouble sometimes for novice users), so I was thinking something like this, if the StringProperty(subtype = 'DIR_PATH') property is relative
I have written a script that demonstrates what I would like to do, but I don't know how to continue and if it is possible to do this.
As you understand (I hope) I try to build an operator which is passed the right argument to interact with it (In this case 2 distinct properties).
import bpy, os

bl_info = {
    &quot;name&quot;: &quot;Test&quot;,
    &quot;author&quot;: &quot;NoobCat&quot;,
    &quot;version&quot;: (1, 0, 0),
    &quot;blender&quot;: (2, 92, 0)
    }

class MYADDON_OT_Realpath(bpy.types.Operator):
    &quot;&quot;&quot;Convert to Realpath&quot;&quot;&quot;
    bl_idname = &quot;myaddon.realpath&quot;
    bl_label = &quot;Realpath&quot;
    bl_options = {'INTERNAL'}
    
    path: bpy.props.StringProperty() # &lt;-- Is useful?
      
    def execute(self,context):
        context.path # &lt;-- Is Useful?
        os.path.realpath(bpy.path.abspath(context.path))# Im very confused 
        return{'FINISHED'}

class LayoutDemoPanel(bpy.types.Panel):
    &quot;&quot;&quot;Creates a Panel in the scene context of the properties editor&quot;&quot;&quot;
    bl_label = &quot;Layout Demo&quot;
    bl_idname = &quot;SCENE_PT_layout&quot;
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = &quot;scene&quot;

    def draw(self, context):
        scn = context.scene
        preferences = bpy.context.preferences.addons[__name__].preferences
        scn_prop = scn.my_props
        
        layout = self.layout
        col = layout.column()
        #Case 1:
        col.prop(scn_prop, 'my_scene_path', text = &quot;Add your scene prop path&quot;)
        if scn_prop.my_scene_path.startswith(&quot;//&quot;):
            path = scn_prop.my_scene_path
            row = col.row()
            #row.context_pointer_set(name=&quot;path&quot;, data=path) &lt;-- Is Useful?
            row.operator(&quot;myaddon.realpath&quot;, text = &quot;Convert to realpath&quot;).path = path
        #Case 2:
        col.prop(preferences, 'my_preferences_path', text = &quot;Add your preferences path&quot;)
        if preferences.my_preferences_path.startswith(&quot;//&quot;):
            path = preferences.my_preferences_path
            row = col.row()
            #row.context_pointer_set(name=&quot;path&quot;, data=path) &lt;-- Is Useful?
            row.operator(&quot;myaddon.realpath&quot;, text = &quot;Convert to realpath&quot;).path = path

class MyAddonPreferences(bpy.types.AddonPreferences):    
    bl_idname = __name__
    my_preferences_path: bpy.props.StringProperty(subtype = 'DIR_PATH')

class SceneProperties(bpy.types.PropertyGroup):
    my_scene_path: bpy.props.StringProperty(subtype = 'DIR_PATH')

classes = (MyAddonPreferences,
           SceneProperties,
           LayoutDemoPanel,
           MYADDON_OT_Realpath)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)  
    bpy.types.Scene.my_props = bpy.props.PointerProperty(type=SceneProperties)
def unregister():
    
    for cls in reversed(classes):       
        bpy.utils.unregister_class(cls)
if __name__ == &quot;__main__&quot;:
    register()
With a setter and getter.
Instead of writing an operator, here is a suggestion re using a boolean property to toggle between the two, and set the path accordingly.
IIRC, (and I didn't) had asked a similar question re globbing string properties with a file or folder subtype, in particular to glob a file.  Have asked a new question.
For the case shown in question, consider adding your own &quot;use relative&quot; property
Have set up a generic setter / getter on path property, and on boolean property the getter simply looks at if the path starts with &quot;//&quot; it is relative, and toggle using the setter.  Will also use the option available in filebrowser of setting relative_path of the invoked and active in the file browser,  operator bpy.ops.buttons.directory_browse()

Example, file saved in tmp folder, draw method added to text editor footer for testing
import bpy

def update(self, context):
    print(&quot;update&quot;)
 
def set(self, value):
    print(&quot;setter&quot;) 
    self[&quot;foo&quot;] = value
         
def get(self):
    return self.get(&quot;foo&quot;, &quot;//&quot;)

bpy.types.Scene.foo = bpy.props.StringProperty(
    subtype='DIR_PATH',
    default=&quot;//&quot;, 
    get=get,
    set=set,
    update=update,
    )
    
def get(self):
    return self.foo.startswith(&quot;//&quot;)

def set(self, value):
    print(&quot;set relative&quot;, value)
    if value:
        self[&quot;foo&quot;] = bpy.path.relpath(self.foo)
    else:
        self[&quot;foo&quot;] = bpy.path.abspath(self.foo)    

bpy.types.Scene.foo_relative_path = bpy.props.BoolProperty(
    name=&quot;Use Relative&quot;,
    get=get,
    set=set,
    )


def draw(self, context):
    layout = self.layout
    row = layout.row(align=True)
    row.prop(context.scene, &quot;foo&quot;)    
    row.prop(context.scene, &quot;foo_relative_path&quot;)



classes = []


def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.TEXT_HT_footer.append(draw)

def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
    bpy.types.TEXT_HT_footer.remove(draw)

if __name__ == &quot;__main__&quot;:
    register()