mel refresh UI trough button question


Hi all
After updating to maya 2017 i found that some script’s windows failed to reopen after certain action.
This script refresh it’s content via restarting itself with button command similar to following:

proc mywindow() {
if (`window -exists "aaa"`) 
    deleteUI -window "aaa"; 
window "aaa";
    scrollLayout scrollLayout; 
    button -c "mywindow();" asdasd;
showWindow "aaa"; 

This code works on maya 2016 just like expected, but on 2017 sometimes (more like 50/50…) after button pressed window wont reopen.
command window -exists aaa;
still shows that that window is open, but i cannot see it which puzzles me

I know that it’s not the best way to make ui, still, I’d rather prefere not to rewrite whole script…

Looking forward to your comments



Did you manage to figure this issue out?
I’m in the same situation and any help to solve it would be greatly appreciated.



I suppose the problem here is that you try to delete a window which is still in use. The button is a child of the windows and as long as the button command is executed, the button exists and therfore the window exists and will refuse the delete command.

In the button command you can try to eval the command deferred:

button -c "evalDeferred(\"mywindow()\");" asdasd;



well, I found a workaround - made a new layout size of a window, put all my content there and instead of closing window i delete that layout.
That works, and does so faster


Thanks for the quick reply folks.
I’m quite new to all this so any help goes a very long way.

Where exactly do i have to put evalDeferred? I’m just not sure what item is getting deferred. Is it the “mywindow” proc you have in your previous example, or the “asdasd”.

Where abouts would I place it in this for example:
button -label “Click me” -c “Run Proc; deleteUI -window MyWindowName; reloadMyScript” ;;

I want it to run the proc, then once that’s done delete the UI and reload my main script.
Randmax, with your method would I just replace the “deleteUI” with “delete” and then my layout name instead of the window name and still have
the reloadMyScript" ;; at the end??

Sorry for the noob questions.



The evalDeferred() wait with the execution of a script until maya is idle, so in your case you should create a seperate funtion an do everything there. At the moment you try to execute three command in the button command what can be a problem with evalDeferred. The very best solution is the way randmax did it. Create all elements which should be rebuilt inside a layout and the button which executes the command outside the layout. This way you can savely delete and rebuild the layout.

Is there any reason why you want to reload your script during execution? That’s not a recommended procedure.


That’s great, thanks for the reply.

The reason I’m reloading the script is so I can populate all the controls within the UI with all the obejct’s attributes.
It seemed like a solid solution as everything work great in maya 2016, until I tried with 17/18.
Is there a better way of doing it?



Reloading a script is only needed if the script itself changes. I suppose your program design is maybe not the optimal one for this task.
If I write it down in pseudocode I’d do it this way:

    createLayout for data and buttons
    createLayout for data (what is the same as rebuildDataLayout see below)

A button is created with:

createButton -command reloadUI()

And reloadUI() would look like this:

delete dataLayout

With this logic, you never need to reload the script. You can even fill the UI automatically as soon as a new object is created with the help of a scriptJob.



Thats how i did it. Note that it was 2 year-ish ago in a rush.


global proc scriptWrapper(string $newFilePath) //proc that sets up static stuff 
    if (`window -exists myScriptWindow`)
        deleteUI -window myScriptWindow;
    window -title "Wrapped Script" -widthHeight 600 300 myScriptWindow;
        string $layout1=`formLayout -numberOfDivisions 3`;
   showWindow myScriptWindow;
proc myScript(string $newFilePath,string $masterLayout) { //main proc, handles dynamic content
    setParent myScriptWindow;
    if ($masterLayout!="") deleteUI -lay $masterLayout; //deleteUI will trow error on empty call
    string $masterLayout = `formLayout -numberOfDivisions 100`;   //master layout that contains all the stuff that needs to be updated, static stuff will be in separate layout
   $newFilePath=$newFilePath+"_1"; //modify button label just to demonstrate that it's new      
   //button calls myScript() proc, which deletes $masterLayout and sets it up anew
   button -bgc 1 1 0.5 -l $newFilePath -c ("myScript(\""+$newFilePath+"\",\""+$masterLayout+"\");") updateButton;  


Awesome, thanks guys!

Will give this a whirl when I’m next freed up.
Again, thanks for all the help. It makes a huge difference.



Amazing, thanks!!!
But don’t work with “dockControl” :frowning: