Dynamic Blender GUI using Python

We are currently developing an application using the Python GUI for Blender and I am hard up in making it dynamic. The main idea is when a button is clicked, a certain menu will be filled up with menu items and images are generated… can someone help me about this? thanks! I would really appreciate your help!

I think this may help, this short program has an if statement in the draw function. When an operator executes the value the if statement is dependent on toggles (therefore the result to the screen changes). The second operator in this program draws a new panel each time it is called. It is very messy though, it is hot where I am, too hot to make it neat and correct the spelling.

# Dynamic Blender GUI using Python
# Example

import bpy
from bpy.props import FloatProperty, PointerProperty, BoolProperty, IntProperty

# ##### ID PROPERTIES #####

class property_class(bpy.types.IDPropertyGroup):
    """
    Fake module like class
    bpy.context.active_object.book_props
    """
    pass

# ##### OPERATORS #####

class BOOK_OT_Change(bpy.types.Operator):
    """Make A Change"""
    bl_idname = "object.change"
    bl_label = "Make A Change"
    bl_description = "It Works"
    
    def execute(self, context):
        ob = context.active_object
        props = ob.new_props
        
        if not props.changed:
            props.p0 = 2 * props.b0
            props.p1 = 2 * props.b1
            props.p2 = 2 * props.b2
            props.changed = True
        else:
            props.b0 = props.p0 / 2
            props.b1 = props.p1 / 2
            props.b2 = props.p2 / 2
            props.changed = False
        
        return {'FINISHED'}
    
class BOOK_OT_newpanel(bpy.types.Operator):
    """Make A Change"""
    bl_idname = "object.panel"
    bl_label = "Make Another Change"
    bl_description = "It Works"
    
    def execute(self, context):
        props = context.active_object.new_props
        
        class OBJECT_PT_NotUseFul(bpy.types.Panel):
            props = context.active_object.new_props
            bl_space_type = 'PROPERTIES'
            bl_region_type = 'WINDOW'
            bl_context = "modifier"
            bl_label = "A Panel"
            bl_idname = "object.mine%i" % props.count
            
            
            def draw(self, context):
                layout = self.layout
                
                
                
                col = layout.column(align=True)
                row = col.row()
                if props.changed:
                    row.prop(props, "p0", slider=True)
                    row.prop(props, "p1", slider=True)
                    row.prop(props, "p2", slider=True)
                else:
                    row.prop(props, "b0")
                    row.prop(props, "b1")
                    row.prop(props, "b2")
                col.operator("object.change")
        
        # Causes an Error
        try:
            bpy.types.register("object.mine%i" % count)
        except:
            pass
        props.count += 1
        return {'FINISHED'}


# #### PANEL #####

class OBJECT_PT_UseFul(bpy.types.Panel):
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "modifier"
    bl_label = "A Panel"
    
    def draw(self, context):
        layout = self.layout
        
        props = context.active_object.new_props
        
        col = layout.column(align=True)
        row = col.row()
        if props.changed:
            row.prop(props, "p0", slider=True)
            row.prop(props, "p1", slider=True)
            row.prop(props, "p2", slider=True)
        else:
            row.prop(props, "b0")
            row.prop(props, "b1")
            row.prop(props, "b2")
        col.operator("object.change")
        col.operator("object.panel")
        
# ##### REGISTER #####

def register():
    # Object Properties
    bpy.types.Object.new_props = PointerProperty(type=property_class)
    property_class.p0 = FloatProperty(name="Num1", default=1)
    property_class.p1 = FloatProperty(name="Wha??", default=1)
    property_class.p2 = FloatProperty(name="Up", default=1)
    
    property_class.b0 = FloatProperty(name="The")
    property_class.b1 = FloatProperty(name="Sky")
    property_class.b2 = FloatProperty(name="Up")
    
    property_class.changed = BoolProperty(default=False)
    
    property_class.count = IntProperty(default=0)

def unregister():
    property_class.p0
    property_class.p1
    property_class.p2
    
    property_class.b0
    property_class.b1
    property_class.b2
    
    property_class.changed
    
    try:
        del bpy.types.Object.new_props
    except:
        pass
    if __name__ == "__main__":
        # unregistering is only done automatically when run as add-on
        bpy.types.unregister(OBJECT_PT_UseFul)

if __name__ == "__main__":
    register()

What do you mean by images (render, texture, material?)

Hope this helps, good luck.

Nice examle ilent2. I have a question. How can we remove the created panel? Is it possible?

To unregister a panel you call bpy.types.unregister(‘PANEL’). So, an example with the script above:

Add this:


class PANEL_OT_remove(bpy.types.Operator):
    """Make A Change"""
    bl_idname = "object.remove"
    bl_label = "Remove A Change"
    bl_description = "It Works"
    
    def execute(self, context):
        bpy.types.unregister(OBJECT_PT_UseFul)
        
        #props.count += 1
        return {'FINISHED'}

and add this line to the draw function of the panel:

col.operator(“object.remove”, icon=‘CANCEL’)

This will remove The first panel. If you want to remove additional panels you create you will need to somehow store the names of these panels.

Thanks for the info ilent2. :slight_smile:

I think this is not the way to do it.
I had recently the same problem. Just using the ‘poll’ function of a Panel is sufficient to decide whether or not to display it.
A multi-step UI can then be achieved using new boolean Property:


def poll(cls,context):
        scene = context.scene
        show = (scene.step1 == 0)
        return show

Sorry I have no time to post a full example. If someone is still interested. Let me know

i tested first script in 636
but get an error on line 9 ?

dynamicpanel1.blend\dynamicpanel1.py", line 9, in <module>
AttributeError: ‘RNA_Types’ object has no attribute ‘IDPropertyGroup’

anybody knows how to correct this

by the way very interesting example
and would like to see the last example
might be usefull in futur !

thanks and happy 2.5