Run Script in PyConsole (Menu)

Execute the code of a textblock within the python console:


This utility adds a menu to the pyconsole console menu (g), from which you can run a textblock inside of the python console. Error messages and print output will appear there instead of the system terminal. You are able to access global variables, functions and classes your script declared, afterwards!

I hope this is useful for quick script testing. Exclusive preview (?) below, please test and report bugs, so I can release it in a bit without worries :slight_smile:

Save code to “console_run_script.py” and install the usual way.

bl_info = {
    "name": "Run Script in PyConsole",
    "author": "CoDEmanX",
    "version": (1, 0),
    "blender": (2, 67, 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 invisible:
                for t in invisible:
                    layout.operator(CONSOLE_OT_run_script.bl_idname, text=t).text = t
            if visible and invisible:
                layout.separator()
            if visible:
                for t in visible:
                    layout.operator(CONSOLE_OT_run_script.bl_idname, text=t, icon='VISIBLE_IPO_ON').text = t
    
def draw_item(self, context):
    layout = self.layout
    layout.menu(CONSOLE_MT_run_script.bl_idname)


def register():
    bpy.utils.register_module(__name__)
    bpy.types.CONSOLE_MT_console.prepend(draw_item)

def unregister():
    bpy.utils.unregister_module(__name__)
    bpy.types.CONSOLE_MT_console.remove(draw_item)    


if __name__ == "__main__":
    register()


3 Likes

Please, put this addOn in Contribs!
Amazing!

awesome :slight_smile:

Very Nice! but maybe it would be better to add a button next to the " Run Script" button?

do you mean between Console menu and Auto complete button? Well, that’s something i thought about, but currently Blender doesn’t let you insert inbetween builtin layout elements. In my snippet system addon, I use a dirty hack to do it anyhow, but not sure how reliable it is together with other addons. I’ll contact Ton again to get this sorted in a nicer way (menus and rest of header as two separate functions in _draw_funcs)

I got only in b.2.76

exec(compile(bpy.data.texts[‘Text’].as_string(), ‘Text’, ‘exec’))

can some explain

@CoDEmanX Nice script! Very useful! Thanks a lot!

I have a button created by my script. I wonder how I can display what the system console displays but inside blender’s console? A simple example I made is here

I made some tweaks to your script to have it run in blender 2.8. Do you have this code hosted somewhere, I can send a Pull Request if you would like.

1 Like

I also did an 2.80 update of this fine script:

5 Likes

One of my favourite. Use it so much. Thx.

my god thank you all for this…I find scripting in blender nightmarish…

I am new so maybe I am ignorant…is there a way to use bpy from an external python ide BUT also open the gui or a window interactively showing the results of your command?

Guys… this scriopt is awesome…

could it be possible to add a new play button in the text editor instead of a drop down menu?

This would be even mopre awesome :slight_smile:

1 Like

precious changing the context so then an operator can be registered from an external script and called in the search menu
import bpy
import os
filepath = “/…/script.py”
global_namespace = {“file”: filepath, “name”: “main”}
with open(filepath, ‘rb’) as file:
exec(compile(file.read(), filepath, ‘exec’), global_namespace)

but a script can call modules too and I need to see this now

1 Like

great!! Saves lots of time!