Skip to content

Instantly share code, notes, and snippets.

@tin2tin
Last active May 11, 2021 18:06
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tin2tin/a48ab242db6f6d9ce6fa36c85464bc1d to your computer and use it in GitHub Desktop.
Save tin2tin/a48ab242db6f6d9ce6fa36c85464bc1d to your computer and use it in GitHub Desktop.
Run Script in the Python Console
bl_info = {
"name": "Run Script in PyConsole",
"author": "CoDEmanX",
"version": (1, 0),
"blender": (2, 80, 0),
"location": "Python Console > Console > Run Script",
"description": "Execute the code of a textblock within the python console.",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Development"}
import bpy
def main(self, context):
text = bpy.data.texts.get(self.text)
if text is not None:
text = "exec(compile(" + repr(text) + ".as_string(), '" + text.name + "', 'exec'))"
bpy.ops.console.clear_line()
bpy.ops.console.insert(text=text)
bpy.ops.console.execute()
class CONSOLE_OT_run_script(bpy.types.Operator):
"""Run a text datablock in PyConsole"""
bl_idname = "console.run_code"
bl_label = "Run script"
text: bpy.props.StringProperty()
@classmethod
def poll(cls, context):
return context.area.type == 'CONSOLE'
def execute(self, context):
main(self, context)
return {'FINISHED'}
def get_texts(context):
l = []
for area in context.screen.areas:
if area.type == 'TEXT_EDITOR':
text = area.spaces[0].text
if text is not None and text not in l:
l.append(text)
return {'visible': [t.name for t in l],
'invisible': [t.name for t in bpy.data.texts if t not in l]}
class CONSOLE_MT_run_script(bpy.types.Menu):
bl_label = "Run Script"
bl_idname = "CONSOLE_MT_run_script"
def draw(self, context):
layout = self.layout
texts = get_texts(context)
visible, invisible = texts['visible'], texts['invisible']
if not (visible or invisible):
layout.label("No text blocks!")
else:
if visible:
for t in visible:
layout.operator(CONSOLE_OT_run_script.bl_idname, text=t, icon='HIDE_OFF').text = t
if visible and invisible:
layout.separator()
if invisible:
for t in invisible:
layout.operator(CONSOLE_OT_run_script.bl_idname, text=t, icon='HIDE_ON').text = t
def draw_item(self, context):
layout = self.layout
layout.menu(CONSOLE_MT_run_script.bl_idname)
layout.operator("script.reload")
layout.separator()
def register():
bpy.utils.register_class(CONSOLE_OT_run_script)
bpy.utils.register_class(CONSOLE_MT_run_script)
bpy.types.CONSOLE_MT_console.prepend(draw_item)
def unregister():
bpy.utils.unregister_class(CONSOLE_OT_run_script)
bpy.utils.unregister_class(CONSOLE_MT_run_script)
bpy.types.CONSOLE_MT_console.remove(draw_item)
if __name__ == "__main__":
register()
@Antyos
Copy link

Antyos commented May 11, 2021

Super useful, thanks! (I know the original was by CodeManX, but I appreciate the updated version!)

Note, if you try to have it run itself through Console > Run Script it crashes Blender (I learned that the hard way just now) so you might want to look into fixing that if possible.

Also, using this same technique, is there any way to add a button in the Text Editor header to run the current script?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment