1
$\begingroup$

I wan't to make an operator that has button in it that is another operator, that would call some method in original operator.

In the example bellow I want to rename object, after I click on Run. Confusing part is that, although execute_function in MineTestClass is called, nothing happens. And then if I call Execute operator from Search menu, it renames object correctly.

import bpy, bmesh
import mathutils
import os
from mathutils import Vector

bpy.types.Scene.current_operator = None


class MineExecuteOperator(bpy.types.Operator):
    bl_idname = "mine.execute_operator"
    bl_label = "Execute operator"

    def execute(self, context):
        print ("Current Operator: " + str(bpy.types.Scene.current_operator))
        bpy.types.Scene.current_operator.execute_function(context)
        return {'FINISHED'}


class MineTestClass(bpy.types.Operator):
    bl_idname = "mine.test_class"
    bl_label = "Test Class"
    bl_options = {'REGISTER', 'UNDO'}

    new_name = bpy.props.StringProperty()

    def execute_function(self, context):
        obj = bpy.context.selected_objects[0]
        obj.name = self.new_name

    def invoke(self, context, event):
        bpy.types.Scene.current_operator = self
        return {"FINISHED"}


    def draw(self, context):
        layout = self.layout
        box = layout.box()
        box.prop(self, 'new_name', expand=True, text="Name")
        box.operator("mine.execute_operator", text="Run")


def register():
    bpy.utils.register_class(MineExecuteOperator)
    bpy.utils.register_class(MineTestClass)


def unregister():
    bpy.utils.unregister_class(MineExecuteOperator)
    bpy.utils.unregister_class(MineTestClass)
$\endgroup$

1 Answer 1

1
$\begingroup$

Let me first say I'm not really sure if this is the way to go.

A registered operator (ie options={'REGISTER', 'UNDO'}) keeps its state, that's why calling a method from another appears to have no effect. The registered operator also needs to have an execute method for 'REDO' to work. For example without the flag in code below a registered op will auto rename whenever the new_name field is changed.

A registered operator when run will be context.active_operator and a history of operators is kept in the context.window_manager.operators list.

Here is one take on what you want to do. Rather than calling a method of the original op from the other, it sets a flag, that if set will rename the object. Once again notice how changing a prop of the reg'd operator prompts a call to execute().

import bpy
from bpy.props import StringProperty, BoolProperty

class MineExecuteOperator(bpy.types.Operator):
    bl_idname = "mine.execute_operator"
    bl_label = "Execute operator"

    def execute(self, context):
        print ("Current Operator: " ,context.active_operator)
        context.active_operator.rename = True
        return {'FINISHED'}

class MineTestClass(bpy.types.Operator):
    bl_idname = "mine.test_class"
    bl_label = "Test Class"
    bl_options = {'REGISTER', 'UNDO'}

    new_name = StringProperty()
    # a flag to rename when set.
    rename = BoolProperty(default=False, options={'SKIP_SAVE'})

    def execute_function(self, context):
        obj = context.object
        obj.name = self.new_name

    def invoke(self, context, event):
        # operator invoked
        return {"FINISHED"}

    # without an execute this wont work with REDO
    def execute(self, context):
        print("EXECUTE")
        if self.rename:
            self.execute_function(context)
            self.rename = False
        return {'FINISHED'}

    def draw(self, context):
        layout = self.layout
        box = layout.box()
        box.prop(self, 'new_name', expand=True, text="Name")
        box.operator("mine.execute_operator", text="Run")

def register():
    bpy.utils.register_class(MineExecuteOperator)
    bpy.utils.register_class(MineTestClass)

def unregister():
    bpy.utils.unregister_class(MineExecuteOperator)
    bpy.utils.unregister_class(MineTestClass)

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

You must log in to answer this question.

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