2
$\begingroup$

I'm working on a task to create the same operator as F2 rename operator inside the blender. I'm stuck at this point because my object names are not refreshing in the operator and also their names are not changing as I'm inputting the value into the string. I hope you understood this because my English is not good enough to explain you.

The thing is my operator is not working properly as it should.

Here is the code:

import bpy

class IMAGES_PT_RENAME(bpy.types.Panel):
    bl_label = "Rename Images"
    bl_idname = "IMAGES_PT_RENAME"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Renamer'
    
    def draw(self, context):
        l = self.layout
        l.operator('flipbook.rename_images')
        
        
class IMAGES_OT_RENAME(bpy.types.Operator):
    bl_label = 'Rename'
    bl_idname = 'flipbook.rename_images'
    op_prop: bpy.props.StringProperty(name= '', default=bpy.context.object.name)
    
    def execute(self, context):
        bpy.context.object.name = self.op_prop
        return {'FINISHED'}
    
    def draw(self, context):
        lay = self.layout
        lay.label(text='Object Name')
        r = lay.row()
        r.label(icon='OBJECT_DATAMODE')
        r.prop(self, 'op_prop',)
        
    def invoke(self, context, event):
        return context.window_manager.invoke_popup(self)
    
classes = [IMAGES_PT_RENAME, IMAGES_OT_RENAME]

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)

if __name__ == "__main__":
    register()
```
$\endgroup$

2 Answers 2

4
$\begingroup$

You want to use bpy.types.WindowManager.invoke_props_dialog

Operator dialog (non-autoexec popup) invoke (show operator properties and only execute it on click on OK button)

instead of bpy.types.WindowManager.invoke_popup

Operator popup invoke (only shows operator’s properties, without executing it)

Also, the correct way to initialize an operator property is not in the annotation definition, since at the time the annotation is registered, the context is not yet initialized so there is not bpy.context.active_object. You can use the invoke method to initialize properties.

Don't :

op_prop: bpy.props.StringProperty(name= '', default=bpy.context.object.name)

Do :

op_prop: bpy.props.StringProperty()

and then

    def invoke(self, context, event):
        self.op_prop = context.active_object.name

Also, since your operator needs an active object to function, you should prevent the user from executing it if there is no active object.


    @classmethod
    def poll(cls, context):
        return context.active_object is not None

The full script :

import bpy

class IMAGES_PT_RENAME(bpy.types.Panel):
    bl_label = "Rename Images"
    bl_idname = "IMAGES_PT_RENAME"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Renamer'
    
    def draw(self, context):
        l = self.layout
        l.operator('flipbook.rename_images')
        
        
class IMAGES_OT_RENAME(bpy.types.Operator):
    bl_label = 'Rename'
    bl_idname = 'flipbook.rename_images'
    op_prop: bpy.props.StringProperty(name= '')
    
    @classmethod
    def poll(cls, context):
        return context.active_object is not None
    
    def execute(self, context):
        context.object.name = self.op_prop
        return {'FINISHED'}
    
    def draw(self, context):
        lay = self.layout
        lay.label(text='Object Name')
        r = lay.row()
        r.label(icon='OBJECT_DATAMODE')
        r.prop(self, 'op_prop',)
        
    def invoke(self, context, event):
        self.op_prop = context.active_object.name
        return context.window_manager.invoke_props_dialog(self)
    
classes = [IMAGES_PT_RENAME, IMAGES_OT_RENAME]

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)

if __name__ == "__main__":
    register()

Note you can also rename the object directly in the panel

import bpy

class IMAGES_PT_RENAME(bpy.types.Panel):
    bl_label = "Rename Images"
    bl_idname = "IMAGES_PT_RENAME"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Renamer'
    
    def draw(self, context):
        if context.active_object is not None:
            self.layout.prop(context.active_object, "name")
$\endgroup$
3
  • $\begingroup$ Thank you for this. Actually I'm new to python then I've learned the Blender python recently. $\endgroup$
    – Muzammil
    Commented Dec 1, 2022 at 13:22
  • $\begingroup$ One question, then how does their operator work without the Ok button? $\endgroup$
    – Muzammil
    Commented Dec 1, 2022 at 14:17
  • $\begingroup$ Because they're directly modifying the object name in the popup, instead of the property of the operator, which does work. But as I explained in my comment I wouldn't recommend since it's not really supported and can lead to unsuspected bugs. $\endgroup$
    – Gorgious
    Commented Dec 1, 2022 at 14:37
0
$\begingroup$
class IMAGES_OT_RENAME(bpy.types.Operator):
    bl_label = 'Rename'
    bl_idname = 'flipbook.rename_images'
    def execute(self, context):
        bpy.context.object.name = self.op_prop
        return {'FINISHED'}
    def draw(self, context):
       self.layout.prop(context.active_object,'name') #<-- here
    def invoke(self, context, event):
        return context.window_manager.invoke_popup(self)

Also see sourse Blender F2 operator.

$\endgroup$
2
  • $\begingroup$ While this seems like a good idea, note that modifying data outside the scope of an operator in an operator popup can cause undefined behaviour or even crashes. For example if your operator poll method depends on the name of the active object and you modify the object name so that the poll now returns falls, your operator will throw an error when you try to execute it. $\endgroup$
    – Gorgious
    Commented Dec 1, 2022 at 11:08
  • $\begingroup$ I did not understand your answer properly I'm new to here. $\endgroup$
    – Muzammil
    Commented Dec 1, 2022 at 13:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .