3
$\begingroup$

i'm currently trying to add presets to the addon i'm developing, while creating and loading those presets works fine, updating the values in the panel that the properties are used in does not work in the way i thougt it would. While other native presets menus like the render resolution menu will update the moment you click on a preset, the values in mine will not. Only after moving the mouse all values in the panel change. Do i have to include an update routine somewhere?

I'm using the same systems blender uses.

Heres my code

    import bpy
    from bl_operators.presets import AddPresetBase
    from bl_ui.utils import PresetPanel
    from bpy.types import Panel, Menu, Operator, WindowManager
    
    
    from bpy.props import (
        BoolProperty,
        StringProperty,
        IntProperty,
        FloatProperty
        )
    
    class CustomProperties(bpy.types.PropertyGroup):
        fps: IntProperty(name="FPS", default=24, min=1, max=244)
        quality: IntProperty(name="Quality", default=75,min=1,max=100)
    
    class My_OP(Operator):
        bl_idname = "my.operator"
        bl_label = 'My Cool OP'
        bl_options = {'PRESET'}
    
    class MY_MT_Presets(Menu):
        bl_label = 'My Presets'
        preset_subdir = 'object/mypresets'
        preset_operator = 'script.execute_preset'
        draw = Menu.draw_preset
        
    
    class OT_AddMyPreset(AddPresetBase, Operator):
        bl_idname = 'my.add_preset'
        bl_label = 'Add a preset'
        preset_menu = 'MY_MT_Presets'
        
        # Common variables used for all preset values
        preset_defines = [
            'obj = bpy.context.object',
            'scene = bpy.context.scene'
        ]
        
        # Properties to store in the preset
        preset_values = [
            'scene.custom_properties.fps',
            'scene.custom_properties.quality'
        ]
        
        # Directory to store the presets
        preset_subdir = 'object/my_presets'
        
    
    
    class MY_PT_presets(PresetPanel, Panel):
        bl_label = 'My Presets'
        preset_subdir = 'object/my_presets'
        preset_operator = 'script.execute_preset'
        preset_add_operator = 'my.add_preset'
    
    class My_PT_Panel(Panel):
        bl_label = 'My Panel'
        bl_space_type = 'PROPERTIES'
        bl_region_type = 'WINDOW'
        bl_context = 'output'
        bl_category = 'Output'
        
        def draw_header_preset(self, _context):
            MY_PT_presets.draw_panel_header(self.layout)
      
        def draw(self, context):
            scene = context.scene
            props = scene.custom_properties
            
            layout = self.layout
            row = layout.row
            layout.prop(props, "fps")
            layout.prop(props, "quality")
    
    def register():
        bpy.utils.register_class(CustomProperties)
        bpy.utils.register_class(My_OP)
        bpy.utils.register_class(MY_MT_Presets)
        bpy.utils.register_class(OT_AddMyPreset)
        bpy.utils.register_class(MY_PT_presets)
        bpy.utils.register_class(My_PT_Panel)
        
        bpy.types.Scene.custom_properties = bpy.props.PointerProperty(type=CustomProperties)
    
    def unregister():
        bpy.utils.unregister_class(CustomProperties)
        bpy.utils.unregister_class(My_OP)
        bpy.utils.unregister_class(MY_MT_Presets)
        bpy.utils.unregister_class(OT_AddMyPreset)
        bpy.utils.unregister_class(MY_PT_presets)
        bpy.utils.unregister_class(My_PT_Panel)
        
        del bpy.types.Scene.custom_properties
    if __name__ == "__main__":
        register()

And here's how it looks in blender. Its located in the Render Output Panel enter image description here

Once you've clicked on a preset, it should update the values in the panel, but only does so once you've moved the mouse out of the black box.

Does anyone know whats the reason for this?

$\endgroup$

2 Answers 2

3
$\begingroup$

This is a different approach

import bpy
from bl_operators.presets import AddPresetBase
from bl_ui.utils import PresetPanel
from bpy.types import Panel, Menu, Operator, WindowManager
from bpy.props import BoolProperty, StringProperty, IntProperty, FloatProperty


class CustomProperties(bpy.types.PropertyGroup):
    fps: IntProperty(name="FPS", default=24, min=1, max=244)
    quality: IntProperty(name="Quality", default=75, min=1, max=100)


class My_OP(Operator):
    bl_idname = "my.operator"
    bl_label = "My Cool OP"
    bl_options = {"PRESET"}


class MY_MT_Presets(Menu):
    bl_label = "My Presets"
    preset_subdir = "object/my_presets"
    preset_operator = "script.execute_preset"
    preset_add_operator = "my.add_preset"
    preset_operator_defaults = {"menu_idname": "MY_MT_Presets"}

    def draw(self, context):
        self.draw_preset(context)


class OT_AddMyPreset(AddPresetBase, Operator):
    bl_idname = "my.add_preset"
    bl_label = "Add a preset"
    preset_menu = "MY_MT_Presets"

    # Directory to store the presets
    preset_subdir = "object/my_presets"

    # Common variables used for all preset values
    preset_defines = ["obj = bpy.context.object", "scene = bpy.context.scene"]

    # Properties to store in the preset
    preset_values = ["scene.custom_properties.fps", "scene.custom_properties.quality"]


class MY_PT_presets(PresetPanel, Panel):
    bl_label = "My Presets"

    def draw(self, context):
        layout = self.layout
        layout.emboss = "PULLDOWN_MENU"
        layout.operator_context = "EXEC_DEFAULT"
        layout.menu_contents("MY_MT_Presets")
        context.area.tag_redraw()


class My_PT_Panel(Panel):
    bl_label = "My Panel"
    bl_space_type = "PROPERTIES"
    bl_region_type = "WINDOW"
    bl_context = "output"
    bl_category = "Output"

    def draw_header_preset(self, _context):
        MY_PT_presets.draw_panel_header(self.layout)

    def draw(self, context):
        scene = context.scene
        props = scene.custom_properties

        layout = self.layout
        row = layout.row
        layout.prop(props, "fps")
        layout.prop(props, "quality")


def register():
    bpy.utils.register_class(CustomProperties)
    bpy.utils.register_class(My_OP)
    bpy.utils.register_class(MY_MT_Presets)
    bpy.utils.register_class(OT_AddMyPreset)
    bpy.utils.register_class(MY_PT_presets)
    bpy.utils.register_class(My_PT_Panel)

    bpy.types.Scene.custom_properties = bpy.props.PointerProperty(type=CustomProperties)


def unregister():
    bpy.utils.unregister_class(CustomProperties)
    bpy.utils.unregister_class(My_OP)
    bpy.utils.unregister_class(MY_MT_Presets)
    bpy.utils.unregister_class(OT_AddMyPreset)
    bpy.utils.unregister_class(MY_PT_presets)
    bpy.utils.unregister_class(My_PT_Panel)

    del bpy.types.Scene.custom_properties


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

Another way:

Add to line 57: def __del__(self): bpy.context.area.tag_redraw()

class MY_PT_presets(PresetPanel, Panel):
    bl_label = 'My Presets'
    preset_subdir = 'object/my_presets'
    preset_operator = 'script.execute_preset'
    preset_add_operator = 'my.add_preset'

    def __del__(self): bpy.context.area.tag_redraw()
$\endgroup$

You must log in to answer this question.

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