How to call Python in Mel and icon-shelve issue

Hi all, I have some trouble in finding ways to call python functions inside of a mel script.

Basically, I have a few Mel scipts in which one creates a new shelf in Maya and inside it, are a few lighting tool button(spotLight, areaLights etc.)

As I am still a noob in scripting, not to mention that so far I have only been studying in python, as for mel I know a little to
none. This is quite a big obstacle for me. I am trying not to edit any of the scripts too much, so as to reduce confusion and any
errors that my occur.

  1. In my startup code, there are a few button which uses .xpm and .png for its icon. In the last few lines, the ext initially is .xpm but I change it to .png which I think it is wrong after I realised that I am still in need of some .xpm icons.
    So is there a OR function in mel?
 global proc shelf_lighting()
        {
	    if (Dpublishmel("objGetMultiConfigs \"objkind\" \""+$show+"\" \"\" \"\" \"maya\" 1", $result))
	    {
	    	string $kindRows[] = stringToStringArray($result[0], ";;");
	    	$objkinds = $kindRows;
	    }

	    string $aboutString = `about -v`;
	    string $aboutStringArr[] = stringToStringArray($aboutString, " ");
	
	    string $versionStringTemp = $aboutStringArr[0];
    	    string $versionString = match("[0-9]+[\.]*[0-9]+", $versionStringTemp);
    	    float $version = $versionString;
	
	    string $pycmd = "evalDeferred \"python(\\\"^1s\\\")\"";

	    string $ext = ".png";
	    if ( int($version) > 2009 )
	    {
		    $ext = ".png";
	    }
  1. I am trying to change the command from “source “rexLightFuncs.mel”;
    rexSpotLightCreate “”;”`;
    to the one as shown in the code below.
    It is a python function and I am trying to incorporate it into mel
 import DLightBuild.DLightBuild as build
        light=build.DLightBuild();light.createLight('spotLight');
The file of this python commands comes from /tools/utils/maya/python/DLightBuild, containing the .py file - DLightBuild, and for some reason, it is not working as I derived this from an example I have seen somewhere in my google search.
$spotLightButton = `shelfButton
            -enableCommandRepeat 1
            -enable 1
            -width 34
            -height 34
            -manage 1
            -visible 1
            -label "Create a Spot Light"
            -image1 "spotLight.png"
            -style "iconOnly"
            -command "import sys;sys.path.insert(0, \"/tools/utils/maya/python/DLightBuild/\");import DLightBuild.DLightBuild as build;reload(build);light=build.DLightBuild(); light.createLight('spotLight')" 
	    -sourceType "python";
  1. Lastly, whenever when I tried to do a test run of my code, to see if the icon image are right and if it is performing the correct function… If I run it just by the shelfButton as seen in the second part of the code (in Mel by the way), it creates a button at the end of my scriptEditor (it is like another docking window below) instead of in my existing shelf or in a new shelf. Any advices on this?

You need to wrap the python in a call to the mel function ‘python’:


string $pycmd =  "import sys;sys.path.insert(0, \"/tools/utils/maya/python/DLightBuild/\");import DLightBuild.DLightBuild as build;reload(build);light=build.DLightBuild(); light.createLight('spotLight')" ;

$spotLightButton = `shelfButton
            -command "python(\"" + $pycmd + "\")";
// other flags skipped

that shouldn’t be necessary if you are setting the -sourceType flag to Python?

does sourcetype=Python work from mel? I had that mentally filed away as ‘no’ but I could be wrong

Hi salik89

  1. the OR operator in MEL must be written ||
int $a = 1;
if ($a > 0 || $a < -1){
    print "OK";
}

and you can clean your code using the getApplicationVersionAsFloat() function :wink:

  1. python accept ’ or " for string, I recommend to use single quote for Python code and double quote for MEL, so you can write :
    -command “import sys;sys.path.insert(0, ‘/tools/utils/maya/python/DLightBuild/’);import DLightBuild.DLightBuild as build;reload(build);light=build.DLightBuild(); light.createLight(‘spotLight’)”
    nothing serious but much cleaner I think :):

Reading your code, I concluded that you have a package (directory) named DLightBuild in /tools/utils/maya/python/DLightBuild/
inside a Python module (file) named DLightBuild containing a class named DLightBuild with a method named createLight, I’m right ?

Maybe the import is wrong… or the path…
Some additional informations is necessary, you’re running a Linux OS ?
When you add a path to your sys.path, you must write an absolute path…
Please, give us your error message.

  1. When you add a button to shelf, you must give the parent flag. The main shelf is stored in a global variable
global string $gShelfTopLevel;

So to get the current tab, I’ve wrote a function :

global proc string getCurrentShelfTab() {
	global string $gShelfTopLevel;
	string $currentTab;
	
	$currentTab = `tabLayout -q -selectTab $gShelfTopLevel`;
	
	return $currentTab;
}

then to use it :

string $currentShelf = `getCurrentShelfTab`
shelfButton -parent $currentShelf...

Hi guys, thanks for getting back to me.

>>> Bioeden
For the qns2, I am trying to read the python file DLightBuild and call one of its function, createLight in it and your conclusion is right.

Then again, at times I keep getting the import error:

Error: No module named DLightBuild

Traceback (most recent call last):

File “<maya console>”, line 1, in <module>

ImportError: No module named DLightBuild

It’s like the import are able to work unless I restart my Maya then after a few attempts it is not working again

The thing now is that, though it is now reading, when i run a portion of the code, but as I write the whole thing, I keep getting the following errors:

// Error:         ; // 
// Error: Line 896.9: Syntax error // 
// Error:     $cmd = "projLightAddPopup( \""+$projLightBtn+"\" );"; // 
// Error: Line 942.10: Syntax error //

Whether I add ; or remove it, still I am getting the syntax errors in which I have no clues at all in how to settle it
Could it due to the fact of the $ sign?

    shelfButton
        -enableCommandRepeat 1
        -enable 1
        -width 34
        -height 34
        -manage 1
        -visible 1
        -annotation "Open the Assignables Linker Window"
        -label "Assignables Window"
        -image1 "LinkerWindow.xpm"
        -style "iconOnly"
        -command "source \"Linker\"; Linker;"
        ;

    $spotLightButton = `shelfButton
        -enableCommandRepeat 1
        -enable 1
        -width 34
        -height 34
        -manage 1
        -visible 1
        -label "Create a Spot Light"
        -image1 "SpotLight.png"
        -style "iconOnly"
        -command "import sys;sys.path.insert(0, '/tools/utils/maya/python/DLightBuild/');import DLightBuild.DLightBuild as build;reload(build);light=build.DLightBuild(); light.createLight('spotLight')"

By the way, supposedly if I wanna to change the utils according to the user such that if userABC opens and load the script, the -command will be:

"import sys;sys.path.insert(0, '/tools/ABC/maya/python/DLightBuild/');import DLightBuild.DLightBuild as build;reload(build);light=build.DLightBuild(); light.createLight('spotLight')"

Will that be possible? I tried to test but apparently there is an error pointing at the $user part

string $user = DGetUser();
print $user;
string $loc = "/tools/" + $user + "/maya/python/dnLightBuilder";

For the Python part:

To solve your import problem, I think there is to much “DLightBuild” in your statement. With your code, DLightBuild() method must be in :
/tools/utils/maya/python/DLightBuild/DLightBuild/DLightBuild.py
Can you tell us if this is correct ?

Then, it’s a bad idea to add the path each time you clic the button. Your sys.path will grow each time you create a light… you can check your sys.path simply with this command :

import sys
from pprint import pprint
pprint(sys.path)

these paths will be scanned by Python interpreter until it found the right script each time you import a module.

In my opinion, you have to add the path in your userSetup.py and resolve the path directly in Python.
In this case, Maya will add the path at startup, and all scripts in this path will be available

import sys
import os
import getpass

SCRIPT_PATH = '/tools/%s/maya/python/DLightBuild/' % getpass.getuser()

if os.path.exists(SCRIPT_PATH):
    sys.path.append(SCRIPT_PATH)

then in Maya button, you have to import module and run the method

import DLightBuild.DLightBuild as build;reload(build);light=build.DLightBuild()

For the MEL part:
no error for me in this block of code

// Error:         ; // 
// Error: Line 896.9: Syntax error // 
// Error:     $cmd = "projLightAddPopup( \""+$projLightBtn+"\" );"; // 
// Error: Line 942.10: Syntax error //

Perhaps you’ve forgotten a parenthesis in previous statements ?

FYI : $ sign is the way you declare a variable in mel, no problem with that.

Turns out I have omitted out a back tick ` in the code itself as some of the shelf buttons carries that.

Everything is working out fine for me.

Thanks a lot for all the advices and help I have gotten from you all :slight_smile: