View Full Version : [mel] Remember Bug

06 June 2012, 05:06 PM
Hi every one, currently have a bug in a set of gui check boxes.

window -title "Noob WIndow"
-wh 200 200
-rtf true

string $base = `formLayout -NumberofDivisions 100`;

string $options[] = {"blank" , "blank", "Blank"};

-numberOfCheckBoxes 3
-labelArray3 "Button 1" "Button 2" "Button 3"
-cw3 75 60 75
-on1 "$options[0] = \"Bob\""
-on2 "$options[1] = \"Bill\""
-on3 "$options[2] = \"Bruce\""
-of1 "$options[0] = \"Blank\""
-of2 "$options[1] = \"Blank\""
-of3 "$options[2] = \"Blank\""
-cc ("int $x = 0;" + "for($x = 0; $x <3; $x++){string $skip = `GuiMod($options[$x])`; if ($options != \"Blank\"({$x = 3;}}")
-en3 false
-va3 false false false
-vis false
formlayout -e -attachForm CheckGrp "left" 20 -attachForm CheckGrp "top" 100 $base;

I've obviously left some things out. the visibility for the group gets turned on via a button after a certain step and criteria have been finished/made. Now the changeCommand is used to control the state of a button (for skipping current step or creating one of the names). I was thinking that on each rehash/source that because the enable3 is false, the state changes and everything would be set back to default and previous choices wouldn't carry over. However, that is not that case and hence the bug.

Lets say I run it once and need a "Bob" in what i'm doing, after words I have to run the script again. But the second time I don't need anyone of the three (Bob/Bill/Bruce) and decided to just skip it and continue- button for it- upon pressing, "Bob" still gets created.

is there something I'm missing? A flag maybe to make sure the State is off- thus the array being all "blank"?

Thank you

06 June 2012, 06:46 PM
Something Else I'm having a problem with is a array that will store a dynamic list of locator names so that "things" can be done with the names. There is a "base" set that will always get created, then "option" sets that get created afterwards which need to be Added too the array.

I tried things like making a temp variable that that got the return name arrays of each Locator "set" (base-options + a few others) but the += couldn't be performed on the "container" array, gave a syntax error.

To Combat that I tried making a procedure that would do it. double temp vairable. One(x) getting the return names arrays for the locator "sets", one (y) getting the return value of the addition procedure. then I did this: $container = $y however at run time, a syntax error is received (did it in a button, but followed a method that worked VERY well already). Usually referring to the X temp variable's usage.

07 July 2012, 01:22 PM
I'm not sure to understand exactly your problem, but if you want to add something at the end of an array, it's:

$myArray [size ($myArray)] = $whateverYouWant;

I'm not sure it helps, but just in case...

07 July 2012, 03:04 PM

While that is something I didn't know, it didn't help. I get the error of Cannot assign data of type String[] to type array element when used like this:

button -label
-command ("$HldrRa = procedure(string1, string2, string3);" + "$acmAra [size($acmAra) = $HldrRa;")

I know that what is being returned to $HldrRa is an Array of strings, or an Empty Array of strings (1 element). Regardless of what is in the returned array, I still get that error.

07 July 2012, 04:52 PM
Your error is caused by trying to add an Array as a single element of another array.

if you need to join two arrays together in MEL, take a look at "stringArrayCatenate"

07 July 2012, 06:06 PM
Kovach, I didn't find anything for stringArrayCatenate, but google searching it did lead me to appendStringArray. Which so far has worked. That solves one problem, however I still have the problem of a "remember bug" where choices from the last time the script was sourced are showing up (even though the GUI shows nothing selected)

07 July 2012, 08:29 PM
A UI should be created fresh each time you run it. Getting a UI to remember the state it was in when a user closed it takes some work storing off the values and saving them in the preferences.

If your UI is remembering options between calls to it, then the problem is likely related to the changeCommand. Are you running any scripts when the UI is spawned, or using scriptJobs?

07 July 2012, 08:41 PM
no ScriptJobs running. I have a rehash;Source Script.mel button built into the GUI right now for quicker updating and checking. From what your saying though, my problem lies in my change command.

07 July 2012, 08:46 PM
try disabling the change command completely and setting "Bob" to On by default.
Change it to Bill and close the UI.
Re-opening it should set it back to Bob.

When a UI is created, it wil just follow the instructions in the main script. If you want it to remember settings, you need to find where they are stored, read them in, and configure the widgets.
Otherwise the widgets should always be created in whatever state they are originally authored.

07 July 2012, 10:17 PM
Kovach, I didn't find anything for stringArrayCatenate, but google searching it did lead me to appendStringArray. Which so far has worked.

appendStringArray is not a MEL command but a script. It does exactly the same thing as the code i gave you, except that there is a for loop so that you can add an array (or part of an array) in another. The way to add one single element in an array by using its size is very simple, i think it's a good trick to remember ;) ...

07 July 2012, 02:14 PM
Ok, haven't had a chance to work in a while, but over the last hour or so I did manage an update. I removed the change command, however the UI still remembers choices from the past iteration. I wonder if just deleting the window is enough?

my deletion sections looks like:

if ((`window -ex WindowName) == true) deleteUI -window WindowName;
if((`windowPref -exists GuiProcName) == 1) windowPref -remove GuiProcName;

That's all I have for the deletion part, maybe deleting the form Layout would work? Only problem is the return value of the layout is passed into a variable declared father down in the Gui Procedure. I'm going to try having the on commands make a call to my "gui editor" procedure, and see if that solves the problem


After working on a new procedure that will add/remove the options (will be needed later for advanced options as well) in just the script editor inside maya- I found that maya was "saving" my array and its information, even after a hash n source.

07 July 2012, 07:45 PM
Old Code

string $options[] = {"blank" , "blank", "Blank"};

-on1 "$options[0] = \"Bob\""
-on2 "$options[1] = \"Bill\""
-on3 "$options[2] = \"Bruce\""
-of1 "$options[0] = \"Blank\""
-of2 "$options[1] = \"Blank\""
-of3 "$options[2] = \"Blank\""

New Code

string $options[];

-numberOfCheckBoxes 3
-labelArray3 "Button 1" "Button 2" "Button 3"
-cw3 75 60 75
-on1 "$options = OptionSwitcher($options, \"Bob\", 1)"
-on2 "$options = OptionSwitcher($options, \"Bill\", 1)"
-on3 "$options = OptionSwitcher($options, \"Bruce\", 1)"
-of1 "$options = OptionSwitcher($options, \"Bob\", 0)"
-of2 "$options = OptionSwitcher($options, \"Bill\", 0)"
-of3 "$options = OptionSwitcher($options, \"Bruce\", 0)"
-en3 false
-va3 false false false
-vis false
formlayout -e -attachForm CheckGrp "left" 20 -attachForm CheckGrp "top" 100 $base;

Changes: Rem0ved -cc flag (didn't correct remember bug- but helped me rethink my methodology of doing what I wanted too).
$options[] now declared as "blank" array
OptionSwitcher(info); added to on off commands.

Ok, created new procedure that loads the "options" into an array and returns that array. The way I have it set up is 1 is on (gets loaded in) and 0 is off (gets removed). The way it works (tested in just script editor) is that it checks to see if "$options" size is 0, if it is then what ever option selected will go into the first place of the array, else option will be added to the end of the array and "$options" gets redefined as the return array. Not really all that complicated.

Now, with just the changes made (and opening a new scene to ensure nothing is saved in memory) I keep getting that $options is an undeclared variable. After reviewing the line#.Letter# I've determined that the error is coming from the assignment "$options = portion and not the procedure portion. I've tried just about every thing to fix this, even changing the variable name to something 3 letters long and having it declared right before the checkboxes and I still get the same error.

07 July 2012, 08:07 AM
I don't get what you really want to do with this script...
But here, the string $options [] is enclosed in a string :
-on1 "$options = OptionSwitcher($options, \"Bob\", 1)"
so it is undeclared. You could use "+" like this :
-on1 ($options + " = OptionSwitcher(" + $options + ", \"Bob\", 1)")
But as $options is an array, it won't work. So you need either to use your code and declare the variable as a global variable (dirty way), either to transform this array in a string (using stringArrayToString). But what I don't understand is why do you use $options in the input of the procedure, as the array is empty? Some code you didn't show here?

Maybe if you tell us more precisely what you wan't to do (maybe you did, but, as you could have understood, English isn't my first language and I could have missed something...) we could help us. I'll try my best ;)

07 July 2012, 12:39 PM

there is a large portion of my code I have not shown, this is just where my problem is, and is the only section that is breaking at the moment.

$options is Declared in the procedure. up where I declare all my variables that will be used in the entire procedure. I learned to declare variables this way back when Learning C and C++ as it made changing/updating variables far easier then having to search through lines of code for each variable declaration- plus Java (if I remember right) has you declare everything at the beginning or the variable will be undeclared.

$options is used in the input of the procedure because I want to "append" it with the option being added or removed. Procedure takes an array ($options), an option (some string value), a integer (between 1 and 0). The integer determines if the the option is going to be added to the array or removed from the array (1 is added 0 is removed). The procedure does one other thing besides appending the array, it modifies the gui. If the array being passed in is blank, as in it is the first time the procedure is being called and the array is blank (how it is because I've declared it as an empty array) it will append the gui to reflect choice. On the other hand if the array passed in gets returned as an empty array, the gui will return to how it was before the selections were made.

07 July 2012, 01:08 PM
since Depkeen has asked for more, I'll provide my entire GUI procedure, just truncated till I reach my problem.

global proc m3nt4lGUI(){
if((`window -ex m3nt4lGUI`) == true) deleteUI -window m3nt4lGUI;
if((`windowPRef -exists m3nt4lGUI) == 1) windowPref -remove m3nt4lGUI;

string $exsits;
string $m3tlRig;
string $m3tlNM;

string $locNms[];
string $RigOpt[];

window -title "M3nt4l AutoRigger"
-width 225
-height 200
-menuBar True
-rtf True

menu -label "about" -tearOff false;
menuItem -lable "My site"
=c "showHelp -a //link to my web site"

string $base = `formLayout -numberofDivisions 100`;
string $defaultText = "Select Mesh, Click Load";

textFieldButtonGrp -label "" -cw3 0 120 50 -buttonLabel "load" -text $defaultText
-buttonCommand ("//Every thing I want the button to do") nmeSet;
//name for button grp
formLayout -e
-attachForm nmeSet "left" 37
-attachForm nmeSet "top" 31

// here on out every thing will be truncated to just what the option is: a radio button, check
//box etc

radioButtonGrp //3 options
formLayout -e // same as above just moved down to be read able

radioButtonGrp // 2 options
formLayout -e // Down and farther in to center

button -label "Create Locators" //Creates Locators as a reference for what will happen
//later in script

//here is problem
checkBoxGrp -numberofCheckBoxes 3 -labelArray3 "Opt1" "Opt2" "opt3" -cw3 55 65 25
-on1 "$RigOpt= OptionSwitcher($RigOpt, \"Opt1\", 1)"
-on2 "$RigOpt= OptionSwitcher($RigOpt, \"Opt2\", 1)"
-on3 "$RigOpt= OptionSwitcher($RigOpt, \"Opt3\", 1)"
-of1 "$RigOpt= OptionSwitcher($RigOpt, \"Opt1\", 0)"
-of2 "$RigOpt= OptionSwitcher($RigOpt, \"Opt2\", 0)"
-of3 "$RigOpt= OptionSwitcher($RigOpt, \"Opt3\", 0)"
-en3 false
-va3 false false false
-vis false
"CheckGrp1"; //1 of 3 but 2 and 3 aren't in yet.
formLayout //Layout for the options spaced far enough down for legability and centered to be the best of my ability

button -label "Skip to next step"


Each button will make the next "part" of the GUI visible as well as run the "options" selected. IE first button runs the options selected from the first 2 radio button grps, then makes checkGrp1 visible and editable. Skip button changes based off selection (nothing selected or your mind gets changed to not want any selection) stays as "skip to next step" and goes on to next step, if you have made a selection it will do something based on that selection- and more than 1 selection has to be executable at one time.

The check box is where I"m stuck because RigOpt is causing the error: $RigOpt is an undeclared variable.

07 July 2012, 03:00 PM
Same problem here, you use the string between quotes, so it is used as a different procedure. Even if you have declared it just before, it isn't recognized when the whole string between quotes is executed. You must declare the string as a global string or to write it like this (assuming $RigOpt is not an array) :
-of3 ($RigOpt + " = OptionSwitcher(" + $RigOpt + ", \"Opt3\", 0)")
As $RigOpt is actually an array, you have to convert it in a string, and then use tokenize to re-convert it to an array...
Why don't you query the information when you need it? Something like:
if (`checkBoxGroup -q -v1 CheckGrp1`)
//do something

07 July 2012, 03:33 PM

I'm not very advanced at using MEL, I just have really good basic foundation to build off of. But lets see if I can grasp what your saying in the 2nd portion, as I really don't want to make a variable global as it will present problems later on.

-of3 ("if (`checkBoxGroup -q -v1 CheckGrp1`) == false/true ){
$RigOpt = OptionSwitcher(" + $RigOpt + ", \"Opt3\", 0);

That is what I think your trying to tell me (I could be very wrong though). The only other way is to have the button open a procedure that does all the query-ing and the rest of the work, but that would make the whole "dynamic" gui/button thing significantly harder (in my mind any way).

07 July 2012, 04:09 PM
That's not what I was thinking about. You don't need to query a state of a checkbox in the check box itself...
I was thinking about querying the information in another procedure. Something like :

global proc PrintSomething ()
//queries the informations we need
if (`checkBoxGrp -q -v1 checkBoxes` && !`checkBoxGrp -q -v2 checkBoxes` && !`checkBoxGrp -q -v3 checkBoxes`)
print "yeah!\n"; //prints only if the first button is selected
button -e -enable true closeWindow; //second button is now enable
warning "oh noooooooo!\n";

global proc test ()
string $exampleWindow = `window`;
-numberOfCheckBoxes 3
-label "Three Buttons"
-labelArray3 "One" "Two" "Three" checkBoxes;

//this button will do something according to what
//is set in the checkBoxGrp
button -label " do it " -c "PrintSomething ();";
//this button is disabled until you check the right button an click on "do it"
button -label " close window " -enable false -c ("deleteUI " + $exampleWindow + ";") closeWindow;
showWindow $exampleWindow;
test ();

Here, when you clic on the "do it" button, it execute a procedure that queries the state of the checkBoxGrp and does an action according to it.

07 July 2012, 04:54 PM
Thank Depkeen-

this is what i'm thinking of doing:

checkBoxGrp -ncb 3 -la3 "Opt1" "Op2" "Opt3" -en false -vis false "cBgNm"
formLayout -e -aF cBgNm "left" # -af cBgNm "top" # $base;
button -label "skip"
-command ("$names = Options( $name )")
-wh # # -vis False -al "center" "BtnName"
formLayout -e -aF BtnName"left" # -af BtnName"top" # $base;

global proc string[] Options( string[] $Names){
string $temp[];

//each Option has own if statement
if(`checkBoxGrp -q -v1 cBgNm`){
$temp = CreationProcedure("Position", "GuiPoint" "Opt1");
appendStringArray ($Names, $temp, size($temp);


This solved my "remember" bug, and some other problems. Thank you Depkeen. To solve the dynamic button I just put a call into the On/Off command of each check box to my gui Editor proc and did the same `checkBoxGrp -q v1 cBGnM` if statment. As long as 1 is on, the label changes. If all are off the Label return to default. I've +rep people that helped.

07 July 2012, 08:57 PM
glad that I could help.
But my name is depAkeen! I already killed for less than that...



CGTalk Moderation
07 July 2012, 08:57 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.