GUI Programming: wait (and retrieve) for OK in an invoke_props_dialog Pop-Up

Hi,
I’m creating a script that shows a pop-up when the user clicks on a button in order to ask a confirm before going on with the script; the problem is that the pop-up doesn’t “wait” for the user pressing “OK”, it just shows the pop-up and goes on with the script, even if the user doesn’t click on the “OK” button.

E.g.:


class PopUpConfirm(bpy.types.Operator): 
    bl_idname = "object.popup_confirm" 
    bl_label = "Operation already done once; click OK to do it again" 
    def execute(self, context): 
        return {'FINISHED'} 
    def invoke(self, context, event): 
        return context.window_manager.invoke_props_dialog(self) 
bpy.utils.register_class(PopUpConfirm) 
 
 
# Somewhere in script... 
if (doneOnce): 
    if bpy.ops.object.popup_confirm('INVOKE_DEFAULT'):    # This doesn't work as (I) expected... 
        doOperation()

(PS: I’m sorry for my bad English XD)

Thank you in advance! :smiley:

it doesn’t work like that, if you call modal ops inside of other ops, the modal op will run in modal mode, but the code of the calling operator will continue and not wait for the modal op to end. There is no real way to do this, at least not one i could recommend.

You should rather place the actual code in execute() and leave the invoke() as it is. Single operator.

I don’t think this is nice either, but should work for your situation:class

PopUpConfirm(bpy.types.Operator):
    bl_idname = "object.popup_confirm" 
    bl_label = "Operation already done once; click OK to do it again" 
    bl_options = {'REGISTER', 'UNDO'}

    done_once = bpy.props.BoolProperty(default=False)


    def execute(self, context): 
        # actual code
        return {'FINISHED'} 


    def invoke(self, context, event): 
        if self.done_once:
            return self.execute(context)
        else:

            return context.window_manager.invoke_props_dialog(self) 


bpy.ops.object.popup_confirm('INVOKE_DEFAULT')


If this is just about preventing the user from executing the same operator again, you should find a cleaner solution, e.g. like removing the ‘UNDO’ option to disable redo panel

bl_options = {‘REGISTER’, ‘UNDO’}

or if user should be able to run once as long as blender runs:

class SimpleOperator(bpy.types.Operator):
    bl_idname = "object.popup_confirm" 
    bl_label = "Operation already done once; click OK to do it again" 
    bl_options = {'REGISTER', 'UNDO'}

    done_once = False

    @classmethod
    def poll(cls, context):
        return not SimpleOperator.done_once

    def execute(self, context): 
        # actual code
        SimpleOperator.done_once = True
        return {'FINISHED'} 

Perfect!
(placed the code in execute())
Thank you very much, CoDEmanX! :wink: