[Scilab-users] ?= GUI hel

Stéphane Mottelet stephane.mottelet at utc.fr
Fri Nov 29 21:13:27 CET 2019


Hello again,

> Le 29 nov. 2019 à 19:55, Claus Futtrup <cfuttrup at gmail.com> a écrit :
> 
> 
> Hi Stéphane
> 
> >In "ge_fs=ge_fs" the lhs is a local copy and the rhs the variable in the calling context.
> 
> I figured something like this was going on, but I don't find it logical. I read this as follows: The ge_r is a global handle, for which the function doesn't have write access. When you assign it to a local variable (it can be the same name, or a new name, I suppose), then suddenly this opens up for writing to it (so you can set the properties). Strange. I don't think even a hardcore programmer can find this to be "pretty code" ... it looks like a hack / a workaround to me.
> 

No hack here. Please see https://wiki.scilab.org/howto/global%20and%20local%20variables

Even the very orthodoxic Julia uses in some similar context  lazy global variables.

S.


> I read your response just as - this is another way to do it - but which way do you personally prefer? ... and why? (maybe execution speed? ... or is there a benefit in flexibility that I cannot see?).
> 
> Best regards,
> Claus
> 
> On 29.11.2019 19:21, Stéphane Mottelet wrote:
>> 
>> Le 29/11/2019 à 19:17, Claus Futtrup a écrit :
>>> Hi Stéphane
>>> 
>>> Hm, you're right. This actually fixes the problem, but I do find it to be a strange "solution" that you write each of them to be equal with itself ... I prefer calling the set() function.
>> In "ge_fs=ge_fs" the lhs is a local copy and the rhs the variable in the calling context.
>> 
>>> 
>>> Cheers,
>>> Claus
>>> 
>>> On 29.11.2019 19:05, Stéphane Mottelet wrote:
>>>> To makeit work, just insert
>>>> 
>>>> ge_r=ge_r;
>>>> ge_fs=ge_fs;
>>>> ge_hz=ge_hz;
>>>> at the begining of function calc.
>>>> 
>>>> My two cents...
>>>> S.
>>>> 
>>>> 
>>>> 
>>>> Le 29/11/2019 à 18:58, Claus Futtrup a écrit :
>>>>> Hi Antoine
>>>>> 
>>>>> >Not much progress because I never managed to get a minimal working example
>>>>> I can repeat my example again and again. It never works. Please see it below.
>>>>> 
>>>>> Do you agree. This consistently fails if you run it from Scinotes editor ... but if I copy e.g. ge_r.visible = "on" to the command line (not from within the calc function), then it shows up.
>>>>> 
>>>>> /Claus
>>>>> 
>>>>> // BAD_GUI_EXAMPLE.SCE
>>>>> //
>>>>> // Demo of how _NOT_ to build a simple GUI in Scilab.
>>>>> 
>>>>> // Initialize variables
>>>>> m = 1; // Moving mass 'm' (kilogram)
>>>>> k = 1; // Stiffness, spring constant 'k' (Newton per meter)
>>>>> fres = 1; // Resonance frequency (Hertz)
>>>>> 
>>>>> function calc()
>>>>>     m = evstr(get(ge_m,"string")); // get content in uicontrol ge_m
>>>>>     k = evstr(get(ge_k,"string")); // get content in uicontrol ge_k
>>>>>     fres=sqrt(k/m)/(2*%pi);
>>>>>     // putting GUI updates inside the calculation routine is not pretty code.
>>>>>     ge_r.visible = "on";
>>>>>     ge_fs.visible = "on";       // THIS DOESN'T WORK
>>>>>     ge_hz.visible = "on";
>>>>> //    set(ge_r,"Visible","on"); // THIS WORKS
>>>>> //    set(ge_fs,"Visible","on");
>>>>> //    set(ge_hz,"Visible","on");
>>>>>     // update global variables
>>>>>     [m,k,fres]=return(m,k,fres);
>>>>> endfunction
>>>>> 
>>>>> function goodbye()
>>>>>     close(ge); // Close GUI window
>>>>>     printf("Resulting fres: %f Hertz\n",fres);
>>>>>     abort // Print result in console (e.g. for copy/paste), then kill the app
>>>>> endfunction
>>>>> 
>>>>> ge = scf(); // GUI Example, Initialize and 'set current figure'
>>>>> as = ge.axes_size; // read size of window, as = [width height]
>>>>> ge.figure_name = "GUI Example"; // Change window header
>>>>> 
>>>>> uicontrol("style","text","string","Moving mass :","position", ..
>>>>>           [10 as(2)-35 80 20],"background",[1 1 1]); // white background
>>>>>           // position properties has four parameters = x,y,width,height
>>>>>           // y-position counts from lower left corner, so we subtract from 'as'
>>>>> ge_m = uicontrol("style","edit","string",string(m), ..
>>>>>           "position",[100 as(2)-35 80 20]);
>>>>> uicontrol("style","text","string"," kg ","position", ..
>>>>>           [200 as(2)-35 30 20],"background",[1 1 1]);
>>>>> 
>>>>> uicontrol("style","text","string","Stiffness   :","position", ..
>>>>>           [10 as(2)-60 80 20],"background",[1 1 1]);
>>>>> ge_k = uicontrol("style","edit","string",string(k), ..
>>>>>           "position",[100 as(2)-60 80 20]);
>>>>> uicontrol("style","text","string"," N/m ","position", ..
>>>>>           [200 as(2)-60 30 20],"background",[1 1 1]);
>>>>> 
>>>>> uicontrol("style","pushbutton","string","Calculate", ..
>>>>>           "position",[10 as(2)-85 80 20],"callback","calc");
>>>>> 
>>>>> ge_r = uicontrol("style","text","string","Result     :","position", ..
>>>>>           [10 as(2)-110 80 20],"visible","off"); // keep these hidden for a start
>>>>> ge_fs = uicontrol("style","text","string",string(fres), ..
>>>>>           "position",[100 as(2)-110 80 20],"visible","off");
>>>>> ge_hz = uicontrol("style","text","string"," Hz ","position", ..
>>>>>           [200 as(2)-110 30 20],"visible","off");
>>>>> 
>>>>> uicontrol("style","pushbutton","string","Exit", ..
>>>>>           "position",[10 as(2)-135 80 20],"callback","goodbye");
>>>>> 
>>>>> On 29.11.2019 10:20, Antoine Monmayrant wrote:
>>>>>> Le Jeudi, Novembre 28, 2019 19:40 CET, Claus Futtrup <cfuttrup at gmail.com> a écrit: 
>>>>>>  
>>>>>>> Hi Antoine
>>>>>>> 
>>>>>>> Also, you should better use get(a, 'propertyName') or set(a, 'propertyName', value) instead of a.propertyName and a.propertyName=value in your callbacks.
>>>>>>> 
>>>>>>> 
>>>>>>> I see what you mean. I just now had trouble turning visibility on/off, 
>>>>>>> but using set(), it works fine. Thanks for the tip.
>>>>>> It's something quite weird, maybe a race condition.
>>>>>> I've seen it when using 'a.prop' or 'a.prop=value' syntax in either a callback function or in a for loop.
>>>>>> When you repeatedly use this syntax, scilab tends to forget that 'a' exists and that it's a handle with different properties.
>>>>>> The initial bug report is here: http://bugzilla.scilab.org/show_bug.cgi?id=15786
>>>>>> Not much progress because I never managed to get a minimal working example (it's an Heisenbug).
>>>>>> 
>>>>>> Antoine
>>>>>> 
>>>>>>> Best regards,
>>>>>>> Claus
>>>>>>> 
>>>>>>> On 28.11.2019 17:47, Antoine Monmayrant wrote:
>>>>>>>> Le Jeudi, Novembre 28, 2019 17:05 CET, Claus Futtrup <cfuttrup at gmail.com> a écrit:
>>>>>>>>   
>>>>>>>>> Hi Antoine, et al.
>>>>>>>>> 
>>>>>>>>> Your reply is very helpful, so I think you got the right question :-)
>>>>>>>>> 
>>>>>>>>> 1) Good point that I can use callback on every uicontrol. This would be
>>>>>>>>> suitable for a simple example (like gui_example.sce) ... but for heavy
>>>>>>>>> calculations, it might be more practical with a CALC button. P.S. The
>>>>>>>>> correct equation for the resonance frequency is fres=sqrt(k/m)/(2*%pi);
>>>>>>>> You are right.
>>>>>>>> Also, the trick to disable the callback function/ reenable it is key for sliders that tend to generate an avalanche of call to the function when one moves the cursor.
>>>>>>>> 
>>>>>>>>> 2) I see what you mean, so not having an empty space, but "show" the
>>>>>>>>> whole she-bang from the beginning. I didn't want to do that (just
>>>>>>>>> deleting the IF-statement), but it could be the best solution in the end
>>>>>>>>> (rather than the inline GUI updates), if nothing better shows up. This
>>>>>>>>> was somehow the "core" of my question. Maybe I ask for too much.
>>>>>>>> I think you can achieve what you want by setting ".visible='off'" for all the uicontrols you don't want to show initialy. You can then set  ".visible='on'" after the first call to the callback (or at each call if you are lazy).
>>>>>>>> 
>>>>>>>>> 3) I will look into this. Thanks for the tip.
>>>>>>>> Also, you should better use get(a, 'propertyName') or set(a, 'propertyName', value) instead of a.propertyName and a.propertyName=value in your callbacks.
>>>>>>>> I have found that this latter syntax is causing a lot of bug if your callback get called really often. I still don't know why.
>>>>>>>> 
>>>>>>>>> 4) I will also look into this. My problem is the steep learning curve.
>>>>>>>>> If you look at the Scilab tutorials you have the good-old Openeering
>>>>>>>>> LHY_Tutorial - it's incredibly complicated and long. Is LHY_Tutorial
>>>>>>>>> using the Model-Viewer-Controller approach? - Maybe the
>>>>>>>>> Model-Viewer-Controller could be presented in a _simple_ tutorial - is
>>>>>>>>> it possible?
>>>>>>>> Hmm, that would be a good idea.
>>>>>>>> I'll see whether I can put something together.
>>>>>>>> The thing is, MVC approach looks rather silly and overengineered on a small example.
>>>>>>>> 
>>>>>>>>> I appreciate gui_example.sce with just about 70 lines of code, two
>>>>>>>>> inputs and one output. I think something like it could help a lot of
>>>>>>>>> people ... and it's not 250 lines of code to get a GUI up and running,
>>>>>>>>> if you know what I mean. The gui_example shows a few differences, like
>>>>>>>>> white versus grey background, editable boxes, etc. In the outputs,
>>>>>>>>> because of the default grey background, you can see the dimensions of
>>>>>>>>> the grid / text-boxes, and gui_example has two buttons. It looks
>>>>>>>>> operational and easy to expand for new users.
>>>>>>>>> 
>>>>>>>>> Cheers,
>>>>>>>>> Claus
>>>>>>>>> 
>>>>>>>>> On 28.11.2019 08:57, Antoine Monmayrant wrote:
>>>>>>>>>> Hello Claus,
>>>>>>>>>> 
>>>>>>>>>> I've been playing a bit with GUIs for teaching, so maybe I can help.
>>>>>>>>>> The issue is that I don't get what your problem is exactly here, so I my answer might be a bit off-topic.
>>>>>>>>>> Do not hesitate to rephrase your issue, I'll try a more focused answer.
>>>>>>>>>> 
>>>>>>>>>> Anywya, here is how I think your code could be improved:
>>>>>>>>>> 
>>>>>>>>>> (1) You can use 'calc' as the callback for all of the editable text field so that your result gets shown right away, without having to press a button.
>>>>>>>>>> (2) You should populate all the uicontrols of your gui first, then only update the displayed values, the visibility of the uicontrols, etc inside your calc function. (ie no more creating a uicontrol inside a callback)
>>>>>>>>>> (3) The 'tag' property of any uicontrol together with 'findobj()' are really nice to get/set the properties of each existing uicontrol.
>>>>>>>>>> (4) You can rely on a proper Model-View-Controler approach (or any other well established method to avoid mixing gui stuff with calculation stuff).
>>>>>>>>>> 
>>>>>>>>>> I attached a small gui I use to illustrate optical anti-reflection coating.
>>>>>>>>>> It is far from perfect (I did not implement a proper model-view-controler for example).
>>>>>>>>>> But you can see how I tried to separate the different parts of the code an how I use findobj/tag/get/set,  etc.
>>>>>>>>>> 
>>>>>>>>>> Hope it helps,
>>>>>>>>>> 
>>>>>>>>>> Antoine
>>>>>>>>>>    
>>>>>>>>>> Le Mercredi, Novembre 27, 2019 19:21 CET, Claus Futtrup <cfuttrup at gmail.com> a écrit:
>>>>>>>>>>    
>>>>>>>>>>> Hi there
>>>>>>>>>>> 
>>>>>>>>>>> I'm trying to build a GUI. For simplicity on the forum, I've built a
>>>>>>>>>>> really simple example of what I'm trying to do. How can I make the
>>>>>>>>>>> "conditional" GUI output work and not have it inside the calc function?
>>>>>>>>>>> ... or, how would you do it? Thanks.
>>>>>>>>>>> 
>>>>>>>>>>> Best regards, Claus.
>>>>>>>>>>> 
>>>>>>>>>>> // GUI_EXAMPLE.SCE
>>>>>>>>>>> //
>>>>>>>>>>> // Demo of how to build a simple GUI in Scilab.
>>>>>>>>>>> // Real simple, with two input variables and one output.
>>>>>>>>>>> // The example uses the basic mechanical example of a mass and a spring as
>>>>>>>>>>> // input parameters and calculates the resonance frequency of the mechanical
>>>>>>>>>>> // system.
>>>>>>>>>>> 
>>>>>>>>>>> // Initialize variables
>>>>>>>>>>> m  =  1;  // Moving mass 'm'(kilogram)
>>>>>>>>>>> k  =  1;  // Stiffness, spring constant 'k'(Newton per meter)
>>>>>>>>>>> fres  =  1;  // Resonance frequency (Hertz)
>>>>>>>>>>> show_result  =  %f;
>>>>>>>>>>> 
>>>>>>>>>>> function  calc()
>>>>>>>>>>>        m  =  evstr(get(ge_m,"string"));  // get content in uicontrol ge_m
>>>>>>>>>>>        k  =  evstr(get(ge_k,"string"));  // get content in uicontrol ge_k
>>>>>>>>>>>        fres  =  sqrt(m  *  k);
>>>>>>>>>>>        // putting GUI updates inside the calculation routine is not pretty code.
>>>>>>>>>>>        uicontrol("style","text","string","Result :","position",  ..
>>>>>>>>>>>                  [10  as(2)-110  80  20]);
>>>>>>>>>>>        uicontrol("style","text","string",string(fres),  ..
>>>>>>>>>>>                  "position",[100  as(2)-110  80  20]);
>>>>>>>>>>>        uicontrol("style","text","string","Hz ","position",  ..
>>>>>>>>>>>                  [200  as(2)-110  30  20]);
>>>>>>>>>>>        show_result  =  %t;
>>>>>>>>>>>        // update global variables
>>>>>>>>>>>        [m,k,fres,show_result]=return(m,k,fres,show_result);
>>>>>>>>>>> endfunction
>>>>>>>>>>> 
>>>>>>>>>>> function  goodbye()
>>>>>>>>>>>        close(ge);  // Close GUI window
>>>>>>>>>>>        printf("Resulting fres: %f Hertz\n",fres);
>>>>>>>>>>>        abort  // Print result in console (e.g. for copy/paste), then kill the app
>>>>>>>>>>> endfunction
>>>>>>>>>>> 
>>>>>>>>>>> ge  =  scf();  // GUI Example, Initialize and 'set current figure'
>>>>>>>>>>> as  =  ge.axes_size;  // read size of window, as = [width height]
>>>>>>>>>>> ge.figure_name  =  "GUI Example";  // Change window header
>>>>>>>>>>> 
>>>>>>>>>>> uicontrol("style","text","string","Moving mass :","position",  ..
>>>>>>>>>>>              [10  as(2)-35  80  20],"background",[1  1  1]);  // white background
>>>>>>>>>>>              // position properties has four parameters = x,y,width,height
>>>>>>>>>>>              // y-position counts from lower left corner, so we subtract from 'as'
>>>>>>>>>>> ge_m  =  uicontrol("style","edit","string",string(m),  ..
>>>>>>>>>>>              "position",[100  as(2)-35  80  20]);
>>>>>>>>>>> uicontrol("style","text","string","kg ","position",  ..
>>>>>>>>>>>              [200  as(2)-35  30  20],"background",[1  1  1]);
>>>>>>>>>>> 
>>>>>>>>>>> uicontrol("style","text","string","Stiffness :","position",  ..
>>>>>>>>>>>              [10  as(2)-60  80  20],"background",[1  1  1]);
>>>>>>>>>>> ge_k  =  uicontrol("style","edit","string",string(k),  ..
>>>>>>>>>>>              "position",[100  as(2)-60  80  20]);
>>>>>>>>>>> uicontrol("style","text","string","N/m ","position",  ..
>>>>>>>>>>>              [200  as(2)-60  30  20],"background",[1  1  1]);
>>>>>>>>>>> 
>>>>>>>>>>> uicontrol("style","pushbutton","string","Calculate",  ..
>>>>>>>>>>>              "position",[10  as(2)-85  80  20],"callback","calc");
>>>>>>>>>>> 
>>>>>>>>>>> // How do I make this "conditional"output show up in my GUI?
>>>>>>>>>>> if  show_result  then  // If "Calculate"button was pushed at least once ...
>>>>>>>>>>>        uicontrol("style","text","string","Result :","position",  ..
>>>>>>>>>>>                  [10  as(2)-110  80  20]);
>>>>>>>>>>>        uicontrol("style","text","string",string(fres),  ..
>>>>>>>>>>>                  "position",[100  as(2)-110  80  20]);
>>>>>>>>>>>        uicontrol("style","text","string","Hz ","position",  ..
>>>>>>>>>>>                  [200  as(2)-110  30  20]);
>>>>>>>>>>> end
>>>>>>>>>>> 
>>>>>>>>>>> uicontrol("style","pushbutton","string","Exit",  ..
>>>>>>>>>>>              "position",[10  as(2)-135  80  20],"callback","goodbye");
>>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> users mailing list
>>>>>>>>>>> users at lists.scilab.org
>>>>>>>>>>> http://lists.scilab.org/mailman/listinfo/users
>>>>>>>> _______________________________________________
>>>>>>>> users mailing list
>>>>>>>> users at lists.scilab.org
>>>>>>>> http://lists.scilab.org/mailman/listinfo/users
>>>>>>> _______________________________________________
>>>>>>> users mailing list
>>>>>>> users at lists.scilab.org
>>>>>>> http://lists.scilab.org/mailman/listinfo/users
>>>>>>> 
>>>>>> _______________________________________________
>>>>>> users mailing list
>>>>>> users at lists.scilab.org
>>>>>> http://lists.scilab.org/mailman/listinfo/users
>>>>> 
>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> users mailing list
>>>>> users at lists.scilab.org
>>>>> https://antispam.utc.fr/proxy/1/c3RlcGhhbmUubW90dGVsZXRAdXRjLmZy/lists.scilab.org/mailman/listinfo/users
>>>> -- 
>>>> Stéphane Mottelet
>>>> Ingénieur de recherche
>>>> EA 4297 Transformations Intégrées de la Matière Renouvelable
>>>> Département Génie des Procédés Industriels
>>>> Sorbonne Universités - Université de Technologie de Compiègne
>>>> CS 60319, 60203 Compiègne cedex
>>>> Tel : +33(0)344234688
>>>> http://www.utc.fr/~mottelet
>>>> 
>>>> 
>>>> _______________________________________________
>>>> users mailing list
>>>> users at lists.scilab.org
>>>> http://lists.scilab.org/mailman/listinfo/users
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> users mailing list
>>> users at lists.scilab.org
>>> https://antispam.utc.fr/proxy/1/c3RlcGhhbmUubW90dGVsZXRAdXRjLmZy/lists.scilab.org/mailman/listinfo/users
>> -- 
>> Stéphane Mottelet
>> Ingénieur de recherche
>> EA 4297 Transformations Intégrées de la Matière Renouvelable
>> Département Génie des Procédés Industriels
>> Sorbonne Universités - Université de Technologie de Compiègne
>> CS 60319, 60203 Compiègne cedex
>> Tel : +33(0)344234688
>> http://www.utc.fr/~mottelet
>> 
>> 
>> _______________________________________________
>> users mailing list
>> users at lists.scilab.org
>> http://lists.scilab.org/mailman/listinfo/users
> 
> _______________________________________________
> users mailing list
> users at lists.scilab.org
> https://antispam.utc.fr/proxy/1/c3RlcGhhbmUubW90dGVsZXRAdXRjLmZy/lists.scilab.org/mailman/listinfo/users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.scilab.org/pipermail/users/attachments/20191129/6c4bc31c/attachment.htm>


More information about the users mailing list