1
$\begingroup$

Following tutorials about how register the hotkey for a script or menu. I always get an error with nameofthefile.py not found or "error in line x" but I copy/paste the whole script.

So lets say i create a new script, from the template Ui_menu.py, how do I set and register the hotkey to run it while modeling ?

$\endgroup$
1
  • $\begingroup$ Without proper operator doing that thing in modeling panel, you cannot assign a hotkey to a script. You can however create an addon, register an operator that run the script by selecting specified text block. Then you can use that id to assign to new shortcut $\endgroup$
    – HikariTW
    Sep 25, 2020 at 4:45

2 Answers 2

1
$\begingroup$

If you need to run any script in any context area. You might need to use a new operator to make the shortcut available due to the lack of operator. The one that scripting editor used will poll the context and only work in scripting area.

enter image description here

enter image description here

enter image description here

Code

import bpy


def create_summary(text: str, length: int = 300) -> str:
    return f"Code Preview:\n\n{text[:length]}"


def list_textname_callback(scene, context):
    return [
        (text.name, text.name, create_summary(text.as_string()))
        for text in bpy.data.texts
    ]


class TEXT_OT_run_specified_script(bpy.types.Operator):
    bl_idname = "text.run_specified_script"
    bl_label = "Run specified text script"
    bl_options = {'REGISTER'}

    # fmt: off
    script_name: bpy.props.EnumProperty(
        name="Run script from:",
        description="Run this specified script.",
        items=list_textname_callback
    )
    # fmt: on

    def invoke(self, context, event):
        # Prompt to ask
        return context.window_manager.invoke_props_dialog(self)

    def execute(self, context):
        script = bpy.data.texts.get(self.script_name, None)
        if script != None:
            exec(
                compile(
                    script.as_string(),
                    filename=f"{script.name}",
                    mode='exec',
                ),
            )
        else:
            self.report({'WARNING'}, "No script found.")
        return {'FINISHED'}


def _menu_func(self, context):
    self.layout.operator(
        TEXT_OT_run_specified_script.bl_idname,
        text=TEXT_OT_run_specified_script.bl_label,
    )


# fmt: off
classes = [
    TEXT_OT_run_specified_script,
]
# fmt: on


def register():
    for c in classes:
        bpy.utils.register_class(c)
        bpy.types.TOPBAR_MT_window.append(_menu_func)


def unregister():
    for c in reversed(classes):
        bpy.utils.unregister_class(c)
        bpy.types.TOPBAR_MT_window.remove(_menu_func)


if __name__ == "__main__":
    try:
        unregister()
    except:
        pass
    register()

Details:

The arbitrary script you want to run is loaded and executed by another operator. Operator is a class inherited from bpy.types.Operator and been registered to Blender system.

Most of the button in Blender is an UI to invoke operator. The short-cut keymap need an bl_idname to hook on. But the original text.run_script (The small play button in your text editor) cannot select arbitrary script and run, also it cannot be run outside the text editor due to the poll method block unnecessary context call.

That's why you need another operator doing the same thing but accept changing script and run it in every where.

TL;DR:

This addon is only a play button that can accessed in anywhere and run any text block (doesn't even need to be a python script). This addon provide a bl_idname for short cut to assign to, make it possible to bind to shortcut.

If anyone here and want this to be a valid addon, go for the github page and download it. It will be put under testing addon.

Github

$\endgroup$
2
  • $\begingroup$ Hi , thank you , this is amazing, and interesting. its a script to "run" any script i left open in the script editor! following your post as guide i finally get myself a shortcut to a custom menu. Right now i understand that i made the script , become an addon. that now is registered in blender at start-up, and inside the addon i defined some, class or operators? and now from the keymap i can add a key to call any operator registered so mine too. i am confused about, Class & operators, make an addon for menu or moving-vertex or duplicate works in the same way? $\endgroup$
    – Est
    Sep 25, 2020 at 15:29
  • $\begingroup$ Roughly the same. Operator is different from menu(Panel). But the whole process should be similar. And worth to note is that from 2.90, you can't search(F3) your addon if it is not registered in any panel. It need to at least append to some menu that search engine can filter it out. $\endgroup$
    – HikariTW
    Sep 26, 2020 at 2:00
0
$\begingroup$

Open a new script , using the template ui_menu

Add these lines to make it able to become an addon

import bpy

bl_info = {
    "name": "MY_OWN_MENU",
    "blender": (2, 80, 0),
    "category": "Object",
}

class CustomMenu(bpy.types.Menu):

Save the file anywhere, using notepad and change the fileextention to .py like "My_custom_menu.py" now in blender -preference- addon , click install addon, and search your file. If done correctly your addon will appear in the window with the "name": "MY_OWN_MENU" set the checkbox active.

Now open the blender-preference-keymap i am not sure of this part, i selected the 3D-view-3DviewGlobal and added a new key at the bottom. maybe this mean that out of the 3d view this key will not work. Since we are calling a menu, write "wm.call_menu" in the first field. this will make appear another field , Write in the exact name of the so: classOBJECT_MT_custom_menu . I read somewhere that f5 f6 f7 f8 area free-key left to user, set the hotkey you prefer. At every startup blender will load the addon, making work the shortcut. going in the addon window, we can uncheck the addon , to set it off, but without deleting her.

$\endgroup$
2
  • $\begingroup$ I am not sure about your method. It seems to be not related to your original question. But yes, if you are going to run a script every time. Make it an addon will do the work $\endgroup$
    – HikariTW
    Sep 26, 2020 at 2:04
  • $\begingroup$ thank you very much. you answer with a great number of info, i will try to understand it fully, $\endgroup$
    – Est
    Sep 26, 2020 at 8:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .