1
$\begingroup$

I made the code below. It does exactly what I want except that the pop up dialog does not go away after pressing "ok" button on the pop up. Basically I want a pop up dialog where the user enters a name for the scene save. I trimmed the code to make it concise here.

Everything seems to work except that after I put a name in the field and press "ok", the dialog still stays there, instead I want it to go away after pressing "ok"

class MYOP(bpy.types.Operator):
    bl_idname = "wm.myop"
    bl_label = "Scene Save"

    name = StringProperty(name="Name", default="") 

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_props_dialog(self)

    def execute(self,context):
        bpy.ops.wm.myop('INVOKE_DEFAULT')
        savescene(context, self.name)

        return {'FINISHED'}

Menu code:

class FILE_MT_SceneSave(bpy.types.Menu):
    bl_label = "SceneSave"
    bl_idname = "FILE_MT_scenesave"

    def draw(self, context):
        layout = self.layout

        scn=context.scene
        wm = context.window_manager
        layout.operator("wm.myop",text="Save")

I am targeting Blender 2.80.

$\endgroup$
5
$\begingroup$

When you press "Ok" you are calling the execute method of the operator, in which you are re-calling your operator. Get rid of bpy.ops.wm.myop('INVOKE_DEFAULT') in the execute method.

Blender 2.8 uses annotations for properties.

Blender 2.8 uses strict naming conventions for operator and panel class names. For the operator with id wm.myop the class needs to be named WM_OT_myop. Please check the system console for errors.

enter image description here

Test script. Added to text menu of text menu for example sake./

import bpy

class WM_OT_myop(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "wm.myop"
    bl_label = "Simple Object Operator"
    # annotations in 2.8
    name : bpy.props.StringProperty(name="Name", default="")

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

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

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_props_dialog(self)

def menu_draw(self, context):
    self.layout.operator("wm.myop")

def register():
    bpy.utils.register_class(WM_OT_myop)
    bpy.types.TEXT_MT_text.append(menu_draw)

def unregister():
    bpy.utils.unregister_class(WM_OT_myop)

if __name__ == "__main__":
    register()

    # test call
    bpy.ops.wm.myop('INVOKE_DEFAULT')

In order to make the operator work as part of a 'floating menu' you have to set the operator_context property of the layout beforehand, which basically allows to display the popup:

import bpy

class WM_OT_myop(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "wm.myop"
    bl_label = "Simple Object Operator"

    name: bpy.props.StringProperty(name="Name", default="")

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

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

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_props_dialog(self)


class Custom_MT_Menu(bpy.types.Menu):
    bl_label = "Custom Menu"
    bl_idname = "OBJECT_MT_custom_menu"

    def draw(self, context):
        layout = self.layout
        layout.operator("wm.save_as_mainfile").copy = True

        layout.operator_context = 'INVOKE_DEFAULT'
        layout.operator("wm.myop")


def register():
    bpy.utils.register_class(Custom_MT_Menu)
    bpy.utils.register_class(WM_OT_myop)


def unregister():
    bpy.utils.unregister_class(Custom_MT_Menu)
    bpy.utils.unregister_class(WM_OT_myop)


if __name__ == "__main__":
    register()

    # The menu can also be called from scripts
    bpy.ops.wm.call_menu(name=Custom_MT_Menu.bl_idname)

Further reading: How to call a confirmation dialog box?

$\endgroup$
  • $\begingroup$ Well it was not there originally (was only part of the invoke functions), but then the pop-up never shows up :( Btw this operator is invoked by a bpy.types.Menu item (via layout.operator) $\endgroup$ – yarun can Feb 18 at 7:01
  • $\begingroup$ I have edited the post, and added a gif, running in 2.8. $\endgroup$ – batFINGER Feb 18 at 7:50
  • $\begingroup$ Thanks your code works, I get it but my issue is that I need to call this operator from a menu like layout.operator("wm.myop",text="Save") and that is my issue. You are able to call the op from the main with bpy.ops which naturally works and that is why I stuck that bpy.ops inside the operator itself. I hope it makes sense. Basically when I call from a menu via layout.operator I cant make it to trigger the pop up. $\endgroup$ – yarun can Feb 18 at 17:56
  • $\begingroup$ I updated my initial post w the menu code $\endgroup$ – yarun can Feb 18 at 18:05
  • $\begingroup$ Thanks I will try it. Meanwhile what I did was to make a secondary operator and call the original operator within that one (after rereading your respond), it seems to work, but your solution sounds more elegant. $\endgroup$ – yarun can Feb 18 at 19:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.