21
$\begingroup$

For some reason, sometimes error messages encountered while scripting are not printed in the info panel, only the message Python script fail, look in the console for now....

One question I have is: Why is this?

I like working with blender full screen, but it gets annoying having to switch back and forth between the terminal and blender while scripting.

Is there anyway to print stdout and stderr (I assume that is where blender is printing these messages) in the UI? (thus also solving the occasional necessity to restart blender because of not starting it from the terminal)

So my other question is: How can I do this?


I realize that this is technically two questions, but they seemed too related to separate.. I'll separate them if it's better that way.

$\endgroup$

4 Answers 4

1
$\begingroup$

For newcomers, I updated the code of CodeManX. Newer versions of blender doesn't have register_module.

import bpy

bl_info = {
    "name": "Run scripts in Python Console",
    "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"}

def get_texts(context):
    l = []
    for area in context.screen.areas:
        if area.type == 'TEXT_EDITOR':
            text = area.spaces.active.text
            if text is not None:
                l.append(text.name)
    return l
class CONSOLE_OT_run_script(bpy.types.Operator):
    """Run a text datablock in Python Console"""
    bl_idname = "console.run_code"
    bl_label = ""

    text : bpy.props.StringProperty()

    @classmethod
    def poll(cls, context):
        return context.area.type == 'CONSOLE'

    def execute(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()
            
        return {'FINISHED'}
    
class CONSOLE_MT_run_script(bpy.types.Menu):
    """Run a text datablock in Python Console"""
    bl_idname = "CONSOLE_MT_run_script"
    bl_label = ""
    bl_description = "Run script"

    def draw(self, context):
        layout = self.layout
        texts = get_texts(context)
        if texts == []:
            layout.label(text="No scripts found")
        for t in texts:
            layout.operator(CONSOLE_OT_run_script.bl_idname, text=t).text = t
    
def draw_func(self, context):
    self.layout.menu(CONSOLE_MT_run_script.bl_idname, icon="PLAY")

classes = (
    CONSOLE_MT_run_script,
    CONSOLE_OT_run_script,
    )

def register():
    for cls in classes:  
        bpy.utils.register_class(cls)
    bpy.types.CONSOLE_HT_header.append(draw_func)
def unregister():
    for cls in classes:  
        bpy.utils.unregister_class(cls)
    bpy.types.CONSOLE_HT_header.remove(draw_func)

if __name__ == '__main__':
    register()
    #unregister()
    
$\endgroup$
16
$\begingroup$

I created a little utility addon that let's you easily run Text datablocks of your .blend (doesn't need to be saved) in the Python Console. Errors will show up there:
Run Script in PyConsole (Menu)

You may also check out the Script Runner addon:
http://goodspiritgraphics.com/software/products/script-runner-addon/

It should be possible to run scripts like with Script Runner, but in the context of the Python Console. Some more info:

http://www.blender.org/documentation/blender_python_api_2_69_release/info_tips_and_tricks.html#executing-external-scripts

$\endgroup$
1
  • $\begingroup$ Great script and addon links. I found that, what the script runner addon accomplishes, can be achieved with this simple trick. Open Python console and execute exec(compile(open("<path-to-script>","r").read(),"script-name","exec")). This way you can use your favorite editor to edit the script, see print messages in python console, no need to open text editor in blender window. $\endgroup$
    – Jayesh
    Commented Aug 26, 2018 at 13:26
11
$\begingroup$

If you do not want to restart Blender to see the messages sent to stdout or stderr, you can always run your script in blenders built-in python console.

This is possible, because you can access all the linked text files of a .blend file you loaded through the bpy.data.texts dictionary.

To get a list of all the text files available you can use the following

bpy.data.texts.keys()

Subsequently that means you can execute the python code in these text file with exec(...), once you turn the text objects into a string with as_string().

For example, to execute the file called script.py inside the blender python console, run the following command in it:

exec(bpy.data.texts['script.py'].as_string())

In this way, any print statements or error messages will now be displayed right there in the built-in console.

$\endgroup$
-1
$\begingroup$

Maybe not the best solution for some practices, but if you're looking for a simple console output method that doesn't require anything outside of Blender and your system, you could try to utilize speech synthesis. You might encounter some problems with longer messages that contain lots of useful information, but for a short print statement or an indication if a particular statement gets reached it works quite well, to name a few examples. An advantage of this approach is, especially considering the problem the OP poses, that you're not required to switch to any other view.

As far as I know, only OS X has a way of doing this out of the box with python, namely with the native 'say' command. You would call it like this:

# At the top of your file 
from os import system
... # Do stuff
system("say %s" % (your_message))
$\endgroup$
1
  • $\begingroup$ On Linux, zenity can be used for that. $\endgroup$
    – user877329
    Commented Apr 23, 2016 at 15:06

You must log in to answer this question.

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