1

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 ?

brockmann
  • 12,613
  • 4
  • 50
  • 93
Est
  • 43
  • 7
  • 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 – HikariTW Sep 25 '20 at 04:45

2 Answers2

2

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

HikariTW
  • 7,821
  • 2
  • 18
  • 37
  • 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?

    – Est Sep 25 '20 at 15:29
  • 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. – HikariTW Sep 26 '20 at 02:00
0

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.

Est
  • 43
  • 7
  • 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 – HikariTW Sep 26 '20 at 02:04
  • thank you very much. you answer with a great number of info, i will try to understand it fully, – Est Sep 26 '20 at 08:32