Add a Keyframe Option to a Button in a Panel I am trying to create add a keyframe option on Buttons in my Panel. As instructed by a tip here, using 
layout.use_property_split = True and  layout.use_property_decorate = True seems to only add a keyframe option to sliders. Is it possible to enable keyframing for buttons?

import bpy
from bpy.props import BoolProperty

win_man = bpy.types.WindowManager
bool_prop = bpy.props.BoolProperty

def update_test(self, context):

    if not context.window_manager.test:
        test = 1 
    else:
        test = 0

    return

win_man.test = bool_prop(default = False, update = update_test)

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):

        wm = context.window_manager
        layout = self.layout
        layout.use_property_split = True
        layout.use_property_decorate = True
        obj = context.object

        col = layout.column()
        col.prop(obj, "location")
        row = self.layout.row()
        sub = row.row()
        label = "test = 1" if wm.test else "test = 0"
        sub.prop(wm, 'test', text=label, toggle=True)

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

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

if __name__ == "__main__":
    register()


Here is the test example used in the previous link with a button property added to demonstrate my point.



from bpy.props import BoolProperty

win_man = bpy.types.WindowManager
bool_prop = bpy.props.BoolProperty

scene_man = bpy.types.Scene

def update_test(self, context):

    if not bpy.context.scene.test:
        bpy.data.objects["Cube"].location[0] = 1

    else:
        bpy.data.objects["Cube"].location[0] = 0

    return

win_man.test = bool_prop(default = False, update = update_test)
scene_man.test = bool_prop(default = False, update = update_test)

class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        loc = bpy.data.objects["Cube"].location[0]
        wm = context.window_manager
        sn = context.scene
        layout = self.layout
        layout.use_property_split = True
        layout.use_property_decorate = True
        obj = context.object

        row = self.layout.row()
        sub = row.row()
        label = "cube = 0" if sn.test else "cube = 1"

        sub.prop(sn, 'test', text=label, toggle=True)

        return
        icon = 'DECORATE_KEYFRAME' if sn.arm_ik else 'DECORATE'
        sub.operator("object.simple_operator", text="", emboss=False, icon=icon)

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

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

if __name__ == "__main__":
    register()


Here is what I tried. The keyframes now work but they don't save the position of the cube, they only seem to affect the button display. How do I make the keyframes react to the location of the cube instead?
Window manager properties are not animatable

Doh.. should have looked harder. The issue here is the use of window manager

&gt;&gt;&gt; C.window_manager.keyframe_insert('test')
Traceback (most recent call last):
  File "&lt;blender_console&gt;", line 1, in &lt;module&gt;
TypeError: bpy_struct.keyframe_insert() property "test" not animatable


Use another ID type, Scene for example and all is sweet.



import bpy
from bpy.props import BoolProperty


def update_test(self, context):

    test = int(self.test)
    return


class HelloWorldPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):

        scene = context.scene
        layout = self.layout
        layout.use_property_split = True
        layout.use_property_decorate = True
        obj = context.object

        col = layout.column()
        col.prop(obj, "location")
        row = self.layout.row()
        sub = row.row()
        label = "test = 1" if scene.test else "test = 0"

        sub.prop(scene, 'test', text=label, toggle=True)

        return
        icon = 'DECORATE_KEYFRAME' if wm.test else 'DECORATE'
        sub.operator("object.simple_operator", text="", emboss=False, icon=icon)


def register():
    bpy.types.Scene.test = BoolProperty()
    bpy.utils.register_class(HelloWorldPanel)


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


if __name__ == "__main__":
    register()


Notice can emulate this with an operator. Have put in the draw method to display only icon for operator (example toggles icon simply using bool value)  Otherwise could pass the path to operator and keyframe insert, change icon based on key at that frame.