Home Coding, Scripting, Shaders

[Mel Script] Dynamic Buttons causing crash

polycounter lvl 10
Offline / Send Message
miica polycounter lvl 10
Hi, I need some help on a mel script, I hope someone can take a bit of time to look at my code and tell me why it doesn't work and how to fix it. I suspect it could even be a Maya bug...

What I am trying to do it create buttons dynamically on the fly using a '+' button. The '+' button will create a new button when I click on it. Each created button has a right click submenu that has a command to delete the button itself.

The problem I ran into is when I delete the button from it's own right click menu, Maya will crash.



This is my code:
<div>/*<br>source dynamic_buttons_test; dynamic_buttons_test;<br>*/<br><br>global proc dynamic_buttons_test()<br>{<br>&nbsp;&nbsp;&nbsp; global string $buttons_rows[];<br>&nbsp;&nbsp;&nbsp; global string $buttons[];<br>&nbsp;&nbsp;&nbsp; global string $add_button;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if (`window -exists dynamic_buttons_test_UI`) deleteUI -wnd dynamic_buttons_test_UI;<br>&nbsp;&nbsp;&nbsp; if (`windowPref -exists dynamic_buttons_test_UI`) windowPref -r dynamic_buttons_test_UI;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; string $window = `window -title "Dynamic Button Test"<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; -widthHeight 300 200<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; "dynamic_buttons_test_UI"`;<br><br>&nbsp;&nbsp;&nbsp; string $main_layout = `columnLayout -adjustableColumn true`;<br><br>&nbsp;&nbsp;&nbsp; int $windowRowSize = 300-15;<br>&nbsp;&nbsp;&nbsp; int $row1col1Size = $windowRowSize * 0.2;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; int $number_of_rows = 4;<br>&nbsp;&nbsp;&nbsp; for ($i=0; $i&lt;$number_of_rows; $i++)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $camera_select_row = `rowLayout -nc 5 -cw5 $row1col1Size $row1col1Size $row1col1Size $row1col1Size $row1col1Size<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -columnAttach5 "both" "both" "both" "both" "both"<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -columnOffset5 3 3 3 3 3<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -columnAlign5 "center" "center" "center" "center" "center"<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; -parent $main_layout`;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $buttons_rows[$i] = $camera_select_row;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; setParent ..;<br><br>&nbsp;&nbsp;&nbsp; showWindow $window;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // Init<br>&nbsp;&nbsp;&nbsp; clear $buttons;<br>&nbsp;&nbsp;&nbsp; on_add_new_button;<br>}<br><br>global proc on_add_new_button()<br>{<br>&nbsp;&nbsp;&nbsp; global string $buttons_rows[];<br>&nbsp;&nbsp;&nbsp; global string $buttons[];<br>&nbsp;&nbsp;&nbsp; global string $add_button;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if (`button -exists $add_button`)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; deleteUI $add_button;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; int $row_number = (`size $buttons`/5);<br>&nbsp;&nbsp;&nbsp; string $row_layout = $buttons_rows[$row_number];<br>&nbsp;&nbsp;&nbsp; string $new_button = `button -h 50 -l "?" -c on_button_click -p $row_layout`;<br>&nbsp;&nbsp;&nbsp; popupMenu;<br>&nbsp;&nbsp;&nbsp; int $button_number = `size $buttons`; // zero based (0 is the first button)<br>&nbsp;&nbsp;&nbsp; menuItem -label "Delete Button" -c ("on_delete_button " + $button_number);<br><br>&nbsp;&nbsp;&nbsp; $buttons[`size $buttons`] = $new_button;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; redraw_add_button;<br>}<br><br>global proc on_delete_button(int $button_number)<br>{<br>&nbsp;&nbsp;&nbsp; global string $buttons[];<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; print2("Delete button number " + $button_number);<br><br>&nbsp;&nbsp;&nbsp; string $delete_button = $buttons[$button_number];<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if (`button -exists $delete_button`)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; deleteUI $delete_button;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; stringArrayRemoveAtIndex($button_number, $buttons);<br>}<br><br>global proc print2(string $message)<br>{<br>&nbsp;&nbsp;&nbsp; print "\n &gt;&gt;&gt;";<br>&nbsp;&nbsp;&nbsp; print $message;<br>&nbsp;&nbsp;&nbsp; print "\n";<br>}<br><br>global proc redraw_add_button()<br>{<br>&nbsp;&nbsp;&nbsp; global string $buttons_rows[];<br>&nbsp;&nbsp;&nbsp; global string $buttons[];<br>&nbsp;&nbsp;&nbsp; global string $add_button;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if (`button -exists $add_button`)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; deleteUI $add_button;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; print2(`size $buttons`);<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; int $row_number = ( `size $buttons`/5);<br>&nbsp;&nbsp;&nbsp; string $row_layout = $buttons_rows[$row_number];<br><br>&nbsp;&nbsp;&nbsp; $add_button = `button -h 50 -l "+" -c on_add_new_button -p $row_layout`;<br>}<br><br>global proc on_button_click()<br>{<br>}<br><br></div>



Replies

  • Panupat
    Offline / Send Message
    Panupat polycounter lvl 13
    You need -control flag to remove the button. I found 2 incorrect instances.

    deleteUI -control $delete_button; 
    deleteUI -control $add_button; 

    Maya really crashed when you miss that flag. So extreme for such simple mistake... more reason to go Python Qt right :D
  • miica
    Offline / Send Message
    miica polycounter lvl 10
    Thank you Panupat! really appreciate your coming to the help, but I added the flags but it still crash  :'(

    I am running the script in Maya LT by the way, because some in the team is using Maya LT and my code needs to be in Mel unfortunately.

    I updated the gist too:



  • Panupat
    Offline / Send Message
    Panupat polycounter lvl 13
    Interesting. Yes this time it crashed... last I tested before replying it worked. Not sure what I did there besudes adding the flag.
    Weird thing is when I tried printing out the button name and run separate MEL command with copy/pasted name, it worked.

    button to delete -&gt; dynamic_buttons_test_UI|columnLayout3|rowLayout2|button25
    deleteUI -control "dynamic_buttons_test_UI|columnLayout3|rowLayout2|button25";
    I thought maybe the pop up was causing the crash but adding a refresh command didn't help either.
  • miica
    Offline / Send Message
    miica polycounter lvl 10
    Hi Panupat, really appreciate your taking the time to figure this out with me :3

    I tried printed out the name and delete manually from the script editor too, somehow it works :o

    I am redesigning the operation of the buttons a bit so the buttons are marked to be deleted and all buttons will be redrawn (minus the ones marked to be deleted) when the 'Add' button is clicked or when user reload the whole script, not elegant.. but that will have to do until I figure out this mystery :'(

  • Panupat
    Offline / Send Message
    Panupat polycounter lvl 13
    I think I narrowed down the cause to the redraw function. Deleting and recreating that + button is what causing the crash. Why I'm not sure, but I think the easiest solution is to create that + button as the first button and then leave it alone in peace.


    EDIT. For some reason, after restarting Maya it crashed again. I don't understand.

    EDIT. deleted the pref folder and it stopped crashing.

    EDIT. Somehow this very line in the pref/windowsPrefs.mel is causing the crash. It gets added every time Maya is closed.

    windowPref -topLeftCorner 346 640 -widthHeight 300 200 -maximized false -parentMain true dynamic_buttons_test_UI;



  • tsungyuw
    Offline / Send Message
    tsungyuw polycounter lvl 5
    try use evalDeferred, I found maya crash a lot when UI is not react fast enough to the command. use evalDeferred can help maya have enough time to do it's job.


    global proc on_delete_button(int $button_number)
    {
        global string $buttons[];
       
        print2("Delete button number " + $button_number);

        string $delete_button = $buttons[$button_number];
       
        if (`button -exists $delete_button`)
        {
            $cmd = ("deleteUI -control " + $delete_button);
            evalDeferred $cmd;
        }
       
        stringArrayRemoveAtIndex($button_number, $buttons);
    }
  • miica
    Offline / Send Message
    miica polycounter lvl 10
    Sorry got a lil bit busy and replying late...

    @Panupat, I think the line added to windowsPrefs.mel is because I got a line that remove the window pref everytime it script run, I think that's why it's get added every time

    if (`windowPref -exists dynamic_buttons_test_UI`) windowPref -r dynamic_buttons_test_UI;


    @tsungyuw, I think it worked! Thanksssssss, I was thinking about trying to delay the delete function by using some sleep(1) function if maya got that thing.. but now I learned to use "evalDeferred", I stumbled upon this command a couple of times now I know what it is :3:3:3

    I also find you got a youtube channel with some interesting maya tools, I will check those out!

    I am gonna have to rewrite my codes again and test again :/

    Cheers!



  • tsungyuw
    Offline / Send Message
    tsungyuw polycounter lvl 5
    It took me a while to find out that delete UI can cause maya crash :)  very strange where you actually don't want the command run too fast.
Sign In or Register to comment.