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_mainfileandwm.read_homefile. I tested with the ui panel template though, I hadn't seen your edit. $\endgroup$