While it is possible for a command to parse flag-like strings directly from the MArgList passed to its doIt() method, that will only work if the command is called from MEL. Python uses a completely different syntax for specifying flags and they are not even accessible from the MArgList.
A syntax object simplifies the task of specifying, validating and parsing your command's flags, and allows you to do so in a manner which will work in both MEL and Python.
When defining flags you need to specify both short and long versions of the flag names. Short flags are three letters or less; long flags are four letters or more.
Define these flags in one place using the #define declaration. For example, scanDagSyntax uses the following flags:
#define kBreadthFlag "-b" #define kBreadthFlagLong "-breadthFirst" #define kDepthFlag "-d" #define kDepthFlagLong "-depthFirst"
In your command class, you need to write a newSyntax method in which the syntax for your command is set up. This method needs to be a static method that returns the syntax object, MSyntax.
Inside your newSyntax method, you need to add the necessary flags to a syntax object and then return it.
The scanDagSyntax class’s newSyntax is defined in the following way:
class scanDagSyntax: public MPxCommand { public: ... static MSyntax newSyntax(); ... }; MSyntax scanDagSyntax::newSyntax() { MSyntax syntax; syntax.addFlag(kBreadthFlag, kBreadthFlagLong); syntax.addFlag(kDepthFlag, kDepthFlagLong); ... return syntax; }
By convention, the arguments to your command are typically parsed in a parseArgs method which is called from doIt. This parseArgs method creates a local MArgDatabase which is initialized with a syntax object and the arguments to the command. MArgDatabase has convenient methods which enable you to determine which flags are set.
MStatus scanDagSyntax::parseArgs(const MArgList &args, MItDag::TraversalType & traversalType, MFn::Type &filter, bool &quiet) { MArgDatabase argData(syntax(), args); if (argData.isFlagSet(kBreadthFlag)) traversalType = MItDag::kBreadthFirst; else if (argData.isFlagSet(kDepthFlag)) traversalType = MItDag::kDepthFirst; ... return MS::kSuccess; }
The MSyntax class allows a flag to be re-used in a command call. For example, you may wish to specify several strings to a command as in:
printDagNodeInfo -name "pSphere1" -name "pSphere2";
Supporting multi use flags in a plug-in command requires some extra coding to find out the positions where the flag repeats. The following code snippet illustrates how to use multi use flags.
#define NFLAG "-nm" #define NFLAGLONG "-name" MSyntax nodeInfo::newSyntax() { MSyntax syntax; syntax.addFlag(NFLAG, NFLAGLONG, MSyntax::kString) ; syntax.makeFlagMultiUse(NFLAG) ; return syntax; } MStatus nodeInfo::parseArgs( const MArgList& args ) { MStatus status = MS::kSuccess; // Arg database and also find the // number of uses of the NFLAG MSyntax syntax = newSyntax(); MArgDatabase parse( syntax, args) ; int num = parse.numberOfFlagUses(NFLAG) ; // Iterate and find all uses of the NFLAG unsigned int pos; for(int i = 0 ; i < num ; i++) { // First we get the position status = parse.getFlagArgumentPosition(NFLAG, i, pos) ; if(status != MS::kSuccess) return status; // Then we get the argument MArgList mArgs1; parse.getFlagArgumentList(NFLAG, i, mArgs1); MString str( mArgs1.asString(0) ); MGlobal::displayInfo( str ); } return status; }
The method that creates the syntax object is registered with the command in the initializePlugin method.