howto/guicontrol - Scilab Wiki

Creating effective control panels and widgets with figure(), uicontrol()

In Scilab 4.x (tk GUI):

This part of Scilab was unfortunately neglected for a long time and essentially left in its beta-1998 state. Yet, it is very viable for building effective GraphicUserInterfaces to scilab scripts, but a number of quirks has to be kept in mind. The neglect state is apparent when looking at the large number of open entries in the bugzilla and recurring questions in the newsgroup.

For Scilab 5, all the GUI interface has been revamped and reimplemented using java widgets. Many of the problems reported should have been addressed and solved. What written in the following refers still to the 4.x implementation and to its tcl/tk innards; while some of the general concepts should apply, the implications of the new design will be discussed elsewhere.

Besides uicontrol()s, Scilab has also a limited number of X-based data entry and info dialogs, such as x_message() or getvalue(). The several advantages of uicontrols, in my opinion, are:

With respect to the last point, the common paradigm of implementation is:

   1 //create the GUI
   2 figure()
   3 h1=uicontrol(...)
   4 h2=uicontrol(...)
   5 //big event loop
   6 exit_condition=%f
   7 while ~exit_condition  //exit condition may be a stop button pressed, or the result of a calculation
   8                        // or a callback (e.g. set on a "pushbutton" uicontrol
   9   var1=get(h1,"value")   //or
  10   var2=eval(get(h2,"string"))  //depending on the actual uicontrol
  11   if var1<>var1_old | var2<>var2_old .... then
  12     var1_old=var1; var2_old=var2; ...
  13     //computations (do them only if input values are changed)
  14     //actions, display of results,...
  15   else
  16    xpause(5e4)  // prevents *continuous* query of the GUI; 50 msec is a reasonable latency time
  17   end
  18 end

Technically, figure/uicontrol are scilab wrappers to a limited subset of tk widgets. Not all of the properties and options of each widget are consistently supported. The widgets are placed on the toplevel (the figure() window) using the place tk geometry manager (not the grid). Therefore, placement is non-hyerarchical (no grouping, no pack) and based only on window coordinates.

Building GUIs based on uicontrols is a sort of intermediate solution. Very simple input tasks don't encourage the complication of building a nice figure(); very complicate GUIs need an amount of fiddling and keeping in mind the actual tk internal translation, which rather encourages an implementation based on a pure tcl script, with all its power.

Some contributed packages which should ease to some extent building complex GUIs: SciGui, UItools, tkgui, "Another graphical user interfa"


Some examples:

(this example uses the patched sci2tcl() of Bug 2512)

Code:

   1 labels1=["particle diameter (nm)","particle density (g/cm³)",..
   2             "gas viscosity µ @ 0°C (N·sec/m²)","gas density @ 0°C, 1atm (kg/m³)",...
   3             "mean free path @ 0°C, 1atm (nm)","gamma, Cv/Cp",..
   4             "Sutherland temperature, °K",..
   5             "Temperature, °K",..
   6             "volume flow rate (standard l/min)"];
   7 values1=string(zeros(1,9));
   8 guiw1=400; guih1=300; guih2=90;
   9 close(1);figure(1,"position",[0,0,guiw1,guih1+20],"figure_name","Aerodynamic Lens Design");
  10 uicontrol(1,"style","text","string","general properties","position",[0,guih1,guiw1,20],...
  11             "horizontalalignment","center","background",[1,1,1]);
  12 for k=1:size(labels1,2)
  13   uicontrol(1,"style","text","string",sci2tcl(labels1(k)),"position",[10,guih1-k*20,200,20],...
  14             "horizontalalignment","left");
  15   guientry(k)=uicontrol(1,"style","edit","string",values1(k),"position",[210,guih1-k*20,180,20],...
  16             "horizontalalignment","left");
  17 end
  18 labels2=["orifice diameters (mm)","tube diameter(s) (mm)","input pressure (Pa)"];
  19 values2=[sci2exp(ones(1,5)),sci2exp(ones(1,5)*10),string(100000)];
  20 uicontrol(1,"style","text","string","telescope parameters","position",[0,guih2,guiw1,20],...
  21             "horizontalalignment","center","background",[1,1,1]);
  22 for k=1:size(labels2,2)
  23   uicontrol(1,"style","text","string",sci2tcl(labels2(k)),"position",[10,guih2-k*20,200,20],...
  24             "horizontalalignment","left");
  25   guientry(k+size(labels1,2))=uicontrol(1,"style","edit","string",sci2tcl(values2(k)),..
  26             "position",[210,guih2-k*20,180,20],"horizontalalignment","left");
  27 end
  28 guivariables=["dp","rhop","mu0","rhog0","lambda0","CvCp","S","T","mdot","df","ds","pin"];
  29 //stop button
  30 guistop=%f;
  31 uicontrol(1,"style","pushbutton","string","Stop","position",[150,5,guiw1/4,25],...
  32             "callback","guistop=%t","horizontalalignment","center","background",[1,0.1,0.1]);
  33 //function for reading all the numbers from the gui
  34 function varargout=getguipars(guientry,guivariables)
  35 //read from gui
  36   for k=1:length(guientry)
  37     ierr=execstr(guivariables(k)+"=eval(get(guientry(k),""string""))","errcatch")
  38 // do something nice if the entry is valid/invalid
  39     if ierr>0 then
  40       bgc=[1,0.8,0.8];
  41     else
  42       bgc=[0.9,0.9,0.9];
  43     end
  44     set(guientry(k),"backgroundColor",bgc)
  45   end
  46 //redimensionalizing and validation
  47 //physics
  48   dp=dp*1e-9; lambda0=lambda0*1e-9; rhop=rhop*1e3; rhog0=rhog0;
  49   rhog=density(%1atm,T)
  50   mdot=mdot*rhog/1000/60;
  51 //telescope
  52   df=df/1000; ds=ds/1000;
  53   if length(ds)<length(df) then ds=[ds(:)',ds(\$)*ones(1,length(df)-length(ds))]; end
  54 // list all together
  55   varargout=list()
  56   for k=1:length(guientry)
  57     execstr("varargout(k)="+guivariables(k))
  58   end
  59 endfunction

This other example uses function uititle of my small toolbox uitools:

   1 // first create the GUI panel
   2   figw=220; figh=160;
   3   close(1)
   4   figure(1,"position",[0 0 figw figh]);
   5 //PUSH TO STOP
   6   hstop=uicontrol(1,"style","pushbutton", "Min",0,"Max",1,"string"," STOP",..
   7              "position",[10 10 50 50],"callback","infiniteloop=%F");
   8 // TRIGGERED MODE
   9   htrig=uicontrol(1,"style","radiobutton","Min",0,"Max",1,"value",0,..
  10                    "position",[80 10 20 20]);
  11   httrig=uititle(htrig,"free/trig","r")
  12 // BINNING x2
  13   hbin=uicontrol(1,"style","radiobutton","Min",0,"Max",1,"value",0,..
  14                    "position",[80 40 20 20]);
  15   htbin=uititle(hbin,"bin x2","r")
  16 // GREYSCALE
  17   hbri=uicontrol("style","slider","Min",1,"Max",255,"value",128,..
  18                   "position",[10 70 200 20]);
  19   htbri=uititle(hbri,"greyscale")
  20 // EXPOSURE (only for untriggered)
  21   hexp=uicontrol("style","slider","Min",1,"Max",1200,"value",40,..
  22                   "position",[10 120 200 20]);
  23   htexp=uititle(hexp,"exposure time")


FAQs:

howto/guicontrol (last edited 2008-05-21 08:54:30 by EnricoSegre)