Maya print in status bar

Hi everyone!

Before Maya 2021 there was this little python hack that made Maya print out information in the status bar by adding a “,” at the end of a print statement.


Now in Maya 2021 with Python 3 this does not work anymore, since print is a function and not a statement anymore.
Did anybody find out how to replicate this functionality in Maya 2021?

Cheers,
Fabian

You could do either of the following:

import pymel.core as pm
pm.displayInfo(‘Hello World!’)

import maya.mel
maya.mel.eval(‘print “Hello World!”’)

1 Like

Thanks @MongoWobbler! Works like a charm! :slight_smile:

1 Like

This sounds like that all is needed is to print without a new line at the end.

Which can be done in Python 3 with the end argument. So I gave that a go:

print('test', end="")

And that didn’t work.

Then for reasons I can’t remember I tried this:

print(end="test")

And hilariously that did work in Maya 2022 to print to the status bar. Go figure.
Note that of course it prints without new line - which is also true for the maya.mel.eval solution.

For details as to why this does work. It seems Python’s C source code for print always uses a separate PyFile_WriteObject call for end even when “empty”. Thus it’s still triggering an update of the status bar. That’s why it does work if you pass it directly in end and pass no arguments. The only PyFile_WriteObject then is only that “end” argument. So technically it could even be faster in Maya to abuse the end argument to print a single value. Hehe. Don’t do it kids. If you’re printing that much that you need to optimize it then look into logging.


Also be aware that Pymel is an optional component in Maya 2022 and thus isn’t necessarily installed on all user’s machines.


It might be worthwhile maybe for Autodesk to update the statusbar to ignore empty lines / new lines. Could be a good feature request maybe?

2 Likes

Here are some more options, and better options for that matter too - especially logging if you’re logging lots of information.

Using logging (recommended)

The logging module also prints out to the statusbar because the default handler uses sys.stdout.write, for example:

# not recommended since it logs using the 'root' logger
import logging
logging.info("test")

And better is using a set logger for your code so logging level can be defined individually.

import logging
logger = logging.getLogger(__name__)
logger.info("test")

More info on logging see the Python documentation.

This works because the default handler for logging uses sys.stdout.write. And even better, it also maps the logging for warnings/errors correctly with the color highlight of the status bar. Bob White mentioned this on Tech Artists Slack:

Yeah, each logging level gets mapped to a thing. Its also what cmds.warning and cmds.error use.
So you get the yellow/red background when doing a logging.warning or logging.error


Using maya.api.OpenMaya.displayInfo

Likely better is using the proper method for these:

import maya.api.OpenMaya as om
om.MGlobal.displayInfo("test")

Credits to Bob White for mentioning this on Slack.


Using sys.stdout.write

Chris Cunningham mentioned on Slack to try sys.stdout.write and that does write nicely to the script editor in Maya 2022 plus gets shown as expected in the statusbar.

import sys
sys.stdout.write("test")

Plus it even shows in the statusbar if you include a new line.

import sys
sys.stdout.write("test\n")

So you could have for example a printstatus function:

import sys

def printstatus(*args, sep=", ", end="\n", flush=True):
    sys.stdout.write(sep.join(args) + end)
    if flush:
        sys.stdout.flush()


# Example usage
printstatus("test")
printstatus("test", "multiple", "args")

Note that the above will raise a SyntaxError in Python 2, so that wouldn’t compile in older versions of Maya. This however would work in both:

import sys


def printstatus(*args, **kwargs):
    sep = kwargs.pop("sep", ", ")
    end = kwargs.pop("end", "\n")
    flush = kwargs.pop("flush", True)
    if kwargs:
        raise TypeError(
            "printstatus() got unexpected keyword "
            "arguments: {}".format(", ".join(kwargs.keys()))
        )

    sys.stdout.write(sep.join(args) + end)
    if flush:
        sys.stdout.flush()


printstatus("test", "multiple", "args")
3 Likes

Hi @BigRoyNL!
Thanks for the really in-depth answer! That must’ve taken some time! Could mark all answers as solution here! :grin:
Cheers