Number Buttons and sharing variables between operator and panel

I’m trying to make an operator file and a panel file to direct it.

Ive got the function done. I creates random vibration along the active object’s F-Curve. I’ve got a panel with a button that executes the operator file.

Right now, the scaling for that vibration is set in the operator. I want to put a number button in the panel to control it.

I’m keeping the value of the tremblorscale in the operator file. I haven’t been able to find out how to properly address the value from within the panel. Nor have I mastered the code for creating a number button.

There is a button labeled Scale in the panel, but its just wired up to the tremblor operator as a place holder for when I can get a real Scale button working.

Any hints would be appreciated. Here’s a test file if you want to see.

Thanks.

tremblor_test.blend (421 KB)

Here is the code to make it a registered operator, which when called from the 3D space will display on the active operator tool panel. Eg call it with spacebar search for “Simple Object…” Your code works well and with a graph editor also open, you can see it live display as you adjust the prop.


import bpy
import mathutils
from bpy.props import FloatProperty

def main(context, tremblorscale):
#    for ob in context.scene.objects:
#        print(ob, "stuff")
    index = 0
    
    scene = context.scene
    ob = scene.objects.active
    originalz = ob.location.z
    context.scene.objects.active = ob
    context.user_preferences.edit.keyframe_new_interpolation_type ='LINEAR'
    endtime = bpy.context.scene.frame_end
    while index <= endtime:
        #set frame
        bpy.context.scene.frame_set(index)
        ob.location.z = originalz + (mathutils.noise.random() * tremblorscale) 
        #bpy.context.scene.frame_set(index)
        bpy.ops.anim.keyframe_insert_menu(type='Location')
        #bpy.ops.action.keyframe_insert('SEL')
        #Add keyframe
        print(bpy.data.objects[1].location.z, ", ", index)
        index = index + 1


class SimpleOperator(bpy.types.Operator):
    def callmain(self, context):
        main(context, self.trem_scale)
        return None
    
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"
    trem_scale = FloatProperty(default=10.0, update=callmain)
    bl_options = {'REGISTER', 'UNDO'}
    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def draw(self, context):
        layout = self.layout
        row = layout.row()
        row.prop(self, "trem_scale")
        
    def execute(self, context):
        main(context, self.trem_scale)
        return {'FINISHED'}


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


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


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.simple_operator()

by giving the trem_scale property an update method, we can also put a slider in the properties panel UI


import bpy


class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Tremblor Panel"
    bl_idname = "OBJECT_PT_Tremblor"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"
    TrembleScale = 2
    
    def draw(self, context):
        layout = self.layout

        obj = context.object

        row = layout.row()
        row.label(text="Tremblor", icon='WORLD_DATA')

        row = layout.row()
        row.label(text="Active object is: " + obj.name)
        row = layout.row()
        row.prop(obj, "name")

        row = layout.row()
        row.operator("object.simple_operator", text="Scale", icon='OBJECT_DATA')
        if getattr(context.active_operator, "name", "") == "Simple Object Operator":
            row = layout.row()
            row.prop(context.active_operator, "trem_scale")
            
        row = layout.row()


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


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


if __name__ == "__main__":
    register()

Thanks. I will try it out tonight.

It does everything that you said it would. I’m learning a lot with playing with it.

The concept I had originally was that the scalar would always be in that panel. You adjust the scalar as you like and then when you hit the Tremblor button, what ever scaling was set was what got done. It wouldn’t get reset by each call of the Simple Operator. But I see what you did and that does the job, but in a different way.

Thank you.