When calling an operator via bpy.ops.*
without any execution context the execute()
method of the respective operator runs by default. If the operator provides any kind of 'user interaction' like a 'confirmation dialog' in this case, then you can pass 'INVOKE_DEFAULT'
as execution context when calling the operator which will also run its invoke()
method:
bpy.ops.wm.read_homefile('INVOKE_DEFAULT')
In order to display the operator as a button and also 'enable' its user interaction, you have to set the operator_context in the 'layout' before calling the operator:
Blender 2.7x
import bpy
class HelloWorldPanel(bpy.types.Panel):
"""Creates a Panel in the Object properties window"""
bl_idname = "CUSTOM_my_panel"
bl_label = "My Panel"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_category = "Tools"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_DEFAULT' #'INVOKE_AREA'
layout.operator("wm.read_homefile", text="New", icon='NEW')
def register():
bpy.utils.register_class(HelloWorldPanel)
def unregister():
bpy.utils.unregister_class(HelloWorldPanel)
if __name__ == "__main__":
register()
Blender 2.8x and beyond
class OBJECT_PT_CustomPanel(bpy.types.Panel):
bl_label = "My Panel"
bl_idname = "OBJECT_PT_custom_panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Tools"
bl_context = "objectmode"
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_DEFAULT' #'INVOKE_AREA'
layout.operator("wm.read_homefile", text="New", icon='FILE_NEW')
def register():
bpy.utils.register_class(OBJECT_PT_CustomPanel)
def unregister():
bpy.utils.unregister_class(OBJECT_PT_CustomPanel)
if __name__ == "__main__":
register()
Custom Confirm Dialog
For a custom conformation dialog you can wrap the operator into another one and invoke invoke_confirm(operator, event)
classmethod of the window-manager to confirm the execution by the user.
Blender 2.7x
import bpy
class SimpleConfirmOperator(bpy.types.Operator):
"""Really?"""
bl_idname = "my_category.custom_confirm_dialog"
bl_label = "Do you really want to do that?"
bl_options = {'REGISTER', 'INTERNAL'}
@classmethod
def poll(cls, context):
return True
def execute(self, context):
self.report({'INFO'}, "YES!")
return {'FINISHED'}
def invoke(self, context, event):
return context.window_manager.invoke_confirm(self, event)
class HelloWorldPanel(bpy.types.Panel):
"""Creates a Panel in the Object properties window"""
bl_idname = "CUSTOM_my_panel"
bl_label = "My Panel"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_category = "Tools"
def draw(self, context):
layout = self.layout
layout.operator(SimpleConfirmOperator.bl_idname)
def register():
bpy.utils.register_class(SimpleConfirmOperator)
bpy.utils.register_class(HelloWorldPanel)
def unregister():
bpy.utils.unregister_class(HelloWorldPanel)
bpy.utils.unregister_class(SimpleConfirmOperator)
if __name__ == "__main__":
register()
Blender 2.8x and beyond
import bpy
class SimpleConfirmOperator(bpy.types.Operator):
"""Really?"""
bl_idname = "my_category.custom_confirm_dialog"
bl_label = "Do you really want to do that?"
bl_options = {'REGISTER', 'INTERNAL'}
@classmethod
def poll(cls, context):
return True
def execute(self, context):
self.report({'INFO'}, "YES!")
return {'FINISHED'}
def invoke(self, context, event):
return context.window_manager.invoke_confirm(self, event)
class OBJECT_PT_CustomPanel(bpy.types.Panel):
bl_label = "My Panel"
bl_idname = "OBJECT_PT_custom_panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Tools"
bl_context = "objectmode"
def draw(self, context):
layout = self.layout
layout.operator(SimpleConfirmOperator.bl_idname)
def register():
bpy.utils.register_class(OBJECT_PT_CustomPanel)
bpy.utils.register_class(SimpleConfirmOperator)
def unregister():
bpy.utils.unregister_class(SimpleConfirmOperator)
bpy.utils.unregister_class(OBJECT_PT_CustomPanel)
if __name__ == "__main__":
register()
Property Confirm
In order to display a popup, some properties and an OK 'button' you can return wm.invoke_props_dialog(self)
instead:
Blender 2.7x
import bpy
class SimplePropConfirmOperator(bpy.types.Operator):
"""Really?"""
bl_idname = "my_category.custom_confirm_dialog"
bl_label = "Do you really want to do that?"
bl_options = {'REGISTER', 'INTERNAL'}
prop1 = bpy.props.BoolProperty()
prop2 = bpy.props.BoolProperty()
@classmethod
def poll(cls, context):
return True
def execute(self, context):
self.report({'INFO'}, "YES!")
return {'FINISHED'}
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
row = self.layout
row.prop(self, "prop1", text="Property A")
row.prop(self, "prop2", text="Property B")
class HelloWorldPanel(bpy.types.Panel):
"""Creates a Panel in the Object properties window"""
bl_idname = "CUSTOM_my_panel"
bl_label = "My Panel"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_category = "Tools"
def draw(self, context):
layout = self.layout
layout.operator(SimplePropConfirmOperator.bl_idname)
def register():
bpy.utils.register_class(SimplePropConfirmOperator)
bpy.utils.register_class(HelloWorldPanel)
def unregister():
bpy.utils.unregister_class(HelloWorldPanel)
bpy.utils.unregister_class(SimplePropConfirmOperator)
if __name__ == "__main__":
register()
Blender 2.8x and beyond
import bpy
class SimplePropConfirmOperator(bpy.types.Operator):
"""Really?"""
bl_idname = "my_category.custom_confirm_dialog"
bl_label = "Do you really want to do that?"
bl_options = {'REGISTER', 'INTERNAL'}
prop1: bpy.props.BoolProperty()
prop2: bpy.props.BoolProperty()
@classmethod
def poll(cls, context):
return True
def execute(self, context):
self.report({'INFO'}, "YES!")
return {'FINISHED'}
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
def draw(self, context):
row = self.layout
row.prop(self, "prop1", text="Property A")
row.prop(self, "prop2", text="Property B")
class OBJECT_PT_CustomPanel(bpy.types.Panel):
bl_label = "My Panel"
bl_idname = "OBJECT_PT_custom_panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Tools"
bl_context = "objectmode"
def draw(self, context):
layout = self.layout
layout.operator(SimplePropConfirmOperator.bl_idname)
def register():
bpy.utils.register_class(OBJECT_PT_CustomPanel)
bpy.utils.register_class(SimplePropConfirmOperator)
def unregister():
bpy.utils.unregister_class(SimplePropConfirmOperator)
bpy.utils.unregister_class(OBJECT_PT_CustomPanel)
if __name__ == "__main__":
register()
Simple Popup
For the sake of completeness, you can also display a popup without any OK button by using wm.invoke_popup(self)
:
import bpy
class SimplePopUpOperator(bpy.types.Operator):
"""Really?"""
bl_idname = "my_category.custom_popup_dialog"
bl_label = "Do you really want to do that?"
bl_options = {'REGISTER', 'INTERNAL'}
prop1: bpy.props.BoolProperty()
prop2: bpy.props.BoolProperty()
@classmethod
def poll(cls, context):
return True
def execute(self, context):
self.report({'INFO'}, "YES!")
return {'FINISHED'}
def invoke(self, context, event):
return context.window_manager.invoke_popup(self)
def draw(self, context):
row = self.layout
row.label(text="Do you really want to do that?")
row.prop(self, "prop1", text="Property A")
row.prop(self, "prop2", text="Property B")
class OBJECT_PT_CustomPanel(bpy.types.Panel):
bl_label = "My Panel"
bl_idname = "OBJECT_PT_custom_panel"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Tools"
bl_context = "objectmode"
def draw(self, context):
layout = self.layout
layout.operator(SimplePopUpOperator.bl_idname)
def register():
bpy.utils.register_class(OBJECT_PT_CustomPanel)
bpy.utils.register_class(SimplePopUpOperator)
def unregister():
bpy.utils.unregister_class(SimplePropConfirmOperator)
bpy.utils.unregister_class(SimplePopUpOperator)
if __name__ == "__main__":
register()
Note: bl_options
of both examples are set to 'INTERNAL'
which excludes the operators from search results, remove it if you'd like to run the operator via space bar/F3.
wm.open_mainfile
andwm.read_homefile
. I tested with the ui panel template though, I hadn't seen your edit. $\endgroup$