Add-On Dev: Button that simply calls a Function? I apologize for the volume of questions. I tried searching for this, but came up with nothing related.

When building an operator window (or panel for that matter), is there any way to setup a simple button -> function relationship? Say, for example, if I had 6 buttons that I wanted to have call 6 separate functions?

If this is not possible, would there be a clever way to create a single operator class that allows its caller to specify a custom function to call when it is executed? Something like this?

op = layout.operator( "wm.function_caller", text="Write Data")
op.function = self.WriteData


I hadn't considered this until writing this question, so I think I will go try some variations on this. If it works, the down-side would be the inability to specify a custom description tool-tip for the buttons, right?

Thanks - any advice is appreciated.

Edit: Just wanted to provide a simple example of where something like this might make sense. If you define an operator window that allows the user to manipulate multiple sets of the same data, you may provide buttons at the top of it to "add" a set, to "subtract" a set, to "move forward" a set in order, to "move back" a set in order, etc. I find it strange that Blender provides a simple callback mechanism for data changes, but doesn't provide one for buttons.
The following example shows how to create multiple operators each with their specific function. It only shows three buttons, but the concept remains the same for an arbitrary number of buttons and their underlying operators. The panel is created in the sidebar of the 3D View which can be opened with N.

I hope I haven't misunderstood what you're trying to accomplish. In case I did, feel free to leave a comment.

bl_info = {
    "name": "Multiple operator example",
    "author": "Robert Guetzkow",
    "version": (1, 0),
    "blender": (2, 80, 0),
    "location": "View3D &gt; Sidebar &gt; My own addon",
    "description": "Example with multiple operators",
    "warning": "",
    "wiki_url": "",
    "category": "3D View"}

import bpy


class EXAMPLE_OT_func_1(bpy.types.Operator):
    bl_idname = "example.func_1"
    bl_label = "Function 1"

    def execute(self, context):
        # Implement your first function here
        self.report({'INFO'}, f"This is {self.bl_idname}")
        return {'FINISHED'}


class EXAMPLE_OT_func_2(bpy.types.Operator):
    bl_idname = "example.func_2"
    bl_label = "Function 2"

    def execute(self, context):
        # Implement your second function here
        self.report({'INFO'}, f"This is {self.bl_idname}")
        return {'FINISHED'}


class EXAMPLE_OT_func_3(bpy.types.Operator):
    bl_idname = "example.func_3"
    bl_label = "Function 3"

    def execute(self, context):
        # Implement your third function here
        self.report({'INFO'}, f"This is {self.bl_idname}")
        return {'FINISHED'}


class EXAMPLE_PT_panel(bpy.types.Panel):
    bl_label = "My own addon"
    bl_category = "Name of your tab"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    def draw(self, context):
        layout = self.layout
        layout.operator(EXAMPLE_OT_func_1.bl_idname)
        layout.operator(EXAMPLE_OT_func_2.bl_idname)
        layout.operator(EXAMPLE_OT_func_3.bl_idname)


classes = (EXAMPLE_OT_func_1, EXAMPLE_OT_func_2, EXAMPLE_OT_func_3, EXAMPLE_PT_panel)


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()