# How to call invoke_popup?

I just can't figure out how to create a custom popup which can receive data etc. What I want to do is let the user select one of the currently selected UV-layers and just hand that back to me. So I created a class like this:

class UVLayerPrompt(Operator):
"""
Prompts the user for the uv-layer he wishes to select for each object
"""
bl_idname = "mhmu.uvprompt"
bl_label = "Choose the uv-layer"

uv_layerPos = 0
def execute(self, context):
print('HI')
def invoke(self, context, event):
self.layout.template_list("UI_UL_list", #is this correct? I guess not...
list_id="UVLayer_LIST", # I guess yes
dataptr=context.object.data, # my guess: yes
propname="uv_textures", # yes?
active_dataptr=context.scene, # I could use some other location, okay
active_propname="uv_layerPos") # I have to assign a IntegerProperty to this, right?
return {'RUNNING_MODAL'}


after I registered my class etc.

when I call window_manager.invoke_popup(UVLayerPrompt) then it says:

TypeError: WindowManager.invoke_popup(): error with argument 1, "operator" - >Function.operator expected a Operator type, not OrderedMeta

I realized that this is not correct. Still I don't know how to react with the context (how do I popup a new instance? with python code ofc?, how do I read the chosen value from that?)

EDIT: I will try to clarify my question: I have an export script that may export several objects. For each of these objects I want to ask the user in a responsive way which uv-texture he wants to be exported. Only one layer per object should be possible and of course I have to call the popup within my script (NOT by the user) and after it run I have to know the result of it.

How far have I gotten with this by now? Using the answer below me I realized that I should use a script that is 'INTERNAL'. Secondly I think I now finally understand how Operators are supposed to work.

I figured out how to do it: if you want to call a script from inside a script you have to call bpy.ops.operator.name('INVOKE_DEFAULT')

invoke_props_dialog(...) seems more appropriate here. It opens a popup with an OK button, and the operator's execute() method will only be called if the user clicks this button. (The other popup types execute on every property change.)

A dynamic EnumProperty is populated automatically with all UV textures of the current object (see uvtex_items callback). It is added to the dialog as expanded prop(...), remove expand=True if you want a dropdown list instead.

invoke_* require an operator instance (object), not an operator class (type). You usually pass self, which is a reference to the operator instance:

import bpy

def uvtex_items(self, context):
return [(t.name, t.name, t.name) for t in context.object.data.uv_textures]

class SimpleOperator(bpy.types.Operator):
"""Tooltip"""
bl_idname = "object.simple_operator"
bl_label = "Simple Object Operator"
bl_options = {'REGISTER', 'UNDO'}

uvtex = bpy.props.EnumProperty(items=uvtex_items)

@classmethod
def poll(cls, context):
return (context.object is not None and
context.object.type == 'MESH' and
len(context.object.data.uv_textures) > 0)

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

def draw(self, context):
layout = self.layout
col = layout.column()
col.prop(self, "uvtex", expand=True)

def execute(self, context):
self.report({'INFO'}, self.uvtex)
return {'FINISHED'}

def register():
bpy.utils.register_class(SimpleOperator)

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

if __name__ == "__main__":
register()


Paste the code into Text Editor and Run Script. Then move your mouse over 3D View, hit Spacebar, search for Simple and run the Simple Object Operator.

• So how would I call a new popup from outside? For each object U want to have the users choice. How would I let Blender open an instance of UVLayerPrompt? – WorldSEnder Jan 25 '14 at 3:56
• So you want to open a sequence of popups, to let the user pick a UV map, with no option to abort this process? Or let the user click some button for each object? Not sure what you mean with uvtex_items, functions are first-class citizens in python. My code requires the active object to be a mesh object with at least one UV map, or Simple Object Operator won't appear in the spacebar menu list. – CodeManX Jan 25 '14 at 10:18
• I clearified the question a bit (in EDIT:) – WorldSEnder Jan 25 '14 at 15:50
• Ah ok, yeah. Well, you need to use a different execution context for a dialog, since its modal handler is added in the invoke method, not execute (but execute is called by default if you call a bpy operator in script, thus the action is taken but without user interaction). – CodeManX Jan 26 '14 at 0:41
• One could also use col.prop_search(self, 'uvtex', context.object.data, 'uv_textures') instead of col.prop(self, 'uvtex', expand=True). This way the user can search for specific names if he has many items. – WorldSEnder Jan 26 '14 at 17:41