Creating dialogs with uicontrol
Contents
In Scilab 5
In the built-in demos
First, look in the demos of Scilab:
demo_gui()
Then look in GUI>Uicontrols 1 and GUI>Uicontrols 2.
To edit the scripts :
editor(fullfile(getlongpathname(SCI),"modules","gui","demos","uicontrol.test.dem.sce")) editor(fullfile(getlongpathname(SCI),"modules","gui","demos","cb_uicontrol_plot3d.dem.sci"))
To run the second script, for example, try:
exec(fullfile(getlongpathname(SCI),"modules","gui","demos","cb_uicontrol_plot3d.dem.sci")); uicontrol_plot3d();
A text
hmain = scf(); h = figure(hmain); h.Position = [0 0 200 20]; huiext=uicontrol(h,"style","text"); huiext.Position = [0 0 200 20]; huiext.String = "My text";
A listbox with a callback
function updatelistbox ( huilist ) disp(huilist.Value) endfunction hmain = scf(); h = figure(hmain); h.Position = [0 0 200 80]; huilist=uicontrol(h,"style","listbox"); huilist.Position = [0 0 200 80]; huilist.String = ["adams" "stiff" "rk" "rkf" "fix"]; huilist.Value = 1; huilist.BackgroundColor=[1 1 1]; huilist.Callback = "updatelistbox";
A slider with a callback
function updateslider(hbri) disp(hbri.Value) endfunction hmain = scf(); h = figure(hmain); h.Position = [0 0 200 20]; hbri=uicontrol("style","slider"); hbri.Min=1; hbri.Max=255; hbri.Value=128; hbri.Position=[0 0 200 20]; hbri.Callback="updateslider";
A button with a callback
function pushmybutton ( huibutton ) disp("Push!") endfunction hmain = scf(); h = figure(hmain); h.Position = [0 0 200 20]; huibutton=uicontrol(h,"style","pushbutton"); huibutton.Position = [0 0 200 20]; huibutton.String = "Update"; huibutton.BackgroundColor=[0.9 0.9 0.9]; huibutton.Callback = "pushmybutton";
Découvrir Scilab/Créer une interface graphique GUI (FR)
https://fr.wikibooks.org/wiki/D%C3%A9couvrir_Scilab/Cr%C3%A9er_une_interface_graphique_GUI
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:
- uicontrols provide radiobuttons, sliders, listboxes, graphisms... which are absent from X-based dialogs
- uicontrols allow (though with some effort -- there is no gui builder) to build complex, customized widget layouts
- X-based data entry dialogs are closed on exit; figure()s can stay open and be queried asynchronously by the running scilab script, thus being true control panels.
With respect to the last point, the common paradigm of implementation is:
//create the GUI figure() h1=uicontrol(...) h2=uicontrol(...) //big event loop exit_condition=%f while ~exit_condition //exit condition may be a stop button pressed, or the result of a calculation // or a callback (e.g. set on a "pushbutton" uicontrol var1=get(h1,"value") //or var2=eval(get(h2,"string")) //depending on the actual uicontrol if var1<>var1_old | var2<>var2_old .... then var1_old=var1; var2_old=var2; ... //computations (do them only if input values are changed) //actions, display of results,... else xpause(5e4) // prevents *continuous* query of the GUI; 50 msec is a reasonable latency time end 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:
labels1=["particle diameter (nm)","particle density (g/cm³)",.. "gas viscosity µ @ 0°C (N·sec/m²)","gas density @ 0°C, 1atm (kg/m³)",... "mean free path @ 0°C, 1atm (nm)","gamma, Cv/Cp",.. "Sutherland temperature, °K",.. "Temperature, °K",.. "volume flow rate (standard l/min)"]; values1=string(zeros(1,9)); guiw1=400; guih1=300; guih2=90; close(1);figure(1,"position",[0,0,guiw1,guih1+20],"figure_name","Aerodynamic Lens Design"); uicontrol(1,"style","text","string","general properties","position",[0,guih1,guiw1,20],... "horizontalalignment","center","background",[1,1,1]); for k=1:size(labels1,2) uicontrol(1,"style","text","string",sci2tcl(labels1(k)),"position",[10,guih1-k*20,200,20],... "horizontalalignment","left"); guientry(k)=uicontrol(1,"style","edit","string",values1(k),"position",[210,guih1-k*20,180,20],... "horizontalalignment","left"); end labels2=["orifice diameters (mm)","tube diameter(s) (mm)","input pressure (Pa)"]; values2=[sci2exp(ones(1,5)),sci2exp(ones(1,5)*10),string(100000)]; uicontrol(1,"style","text","string","telescope parameters","position",[0,guih2,guiw1,20],... "horizontalalignment","center","background",[1,1,1]); for k=1:size(labels2,2) uicontrol(1,"style","text","string",sci2tcl(labels2(k)),"position",[10,guih2-k*20,200,20],... "horizontalalignment","left"); guientry(k+size(labels1,2))=uicontrol(1,"style","edit","string",sci2tcl(values2(k)),.. "position",[210,guih2-k*20,180,20],"horizontalalignment","left"); end guivariables=["dp","rhop","mu0","rhog0","lambda0","CvCp","S","T","mdot","df","ds","pin"]; //stop button guistop=%f; uicontrol(1,"style","pushbutton","string","Stop","position",[150,5,guiw1/4,25],... "callback","guistop=%t","horizontalalignment","center","background",[1,0.1,0.1]); //function for reading all the numbers from the gui function varargout=getguipars(guientry,guivariables) //read from gui for k=1:length(guientry) ierr=execstr(guivariables(k)+"=eval(get(guientry(k),""string""))","errcatch") // do something nice if the entry is valid/invalid if ierr>0 then bgc=[1,0.8,0.8]; else bgc=[0.9,0.9,0.9]; end set(guientry(k),"backgroundColor",bgc) end //redimensionalizing and validation //physics dp=dp*1e-9; lambda0=lambda0*1e-9; rhop=rhop*1e3; rhog0=rhog0; rhog=density(%1atm,T) mdot=mdot*rhog/1000/60; //telescope df=df/1000; ds=ds/1000; if length(ds)<length(df) then ds=[ds(:)',ds(\$)*ones(1,length(df)-length(ds))]; end // list all together varargout=list() for k=1:length(guientry) execstr("varargout(k)="+guivariables(k)) end endfunction
This other example uses function uititle of my small toolbox uitools:
// first create the GUI panel figw=220; figh=160; close(1) figure(1,"position",[0 0 figw figh]); //PUSH TO STOP hstop=uicontrol(1,"style","pushbutton", "Min",0,"Max",1,"string"," STOP",.. "position",[10 10 50 50],"callback","infiniteloop=%F"); // TRIGGERED MODE htrig=uicontrol(1,"style","radiobutton","Min",0,"Max",1,"value",0,.. "position",[80 10 20 20]); httrig=uititle(htrig,"free/trig","r") // BINNING x2 hbin=uicontrol(1,"style","radiobutton","Min",0,"Max",1,"value",0,.. "position",[80 40 20 20]); htbin=uititle(hbin,"bin x2","r") // GREYSCALE hbri=uicontrol("style","slider","Min",1,"Max",255,"value",128,.. "position",[10 70 200 20]); htbri=uititle(hbri,"greyscale") // EXPOSURE (only for untriggered) hexp=uicontrol("style","slider","Min",1,"Max",1200,"value",40,.. "position",[10 120 200 20]); htexp=uititle(hexp,"exposure time")
FAQs:
- figure() and graphic windows are different beasts [in Scilab up to 4.x]. It is not possible to place uicontrols in graphic windows, as it would be in Matlab.
User interaction in scilab graphic windows can be handled with xclick() and seteventhandler() -- to build a GUI on that alone is very impervious, but alas, this is how Scicos is built after all.
the "edit" uicontrol (wrapping tk entry) does not support multiline input, while the "text" uicontrol (wrapping tk label) does (but it is not user editable).
Tcl sensible characters in strings, such as [], {}, ";", spaces and quotes, have often (depending on the context) to be escaped with multiple \ (which is the tcl escape) or enclosed in curly brackets {} (which forces no tcl substitution in strings). The rule should be that "strings" need to be escaped once (i.e., "[ ]" has to be written "\[\ \]", while callbacks commands have to be escaped twice ("\\\[\\\ \\\]"), beacuse they are tcl-substituted twice (this is indeed a bug of sloppy argument passing in tclsci). See for instance discussion in Bug 302, Bug 596, Bug 2111 For extended ASCII characters, see comments in Bug 2512.
known uicontrol limitations (Request 82):
- scilab does not allow vertical sliders;
- checkbox==radiobutton,
- slider has only smallstep, no side arrows;
- foreground color is always grey,
- pressed radio/check always pale red,
- only pushbutton, radiobutton, checkbox, slider support callback)
to get the true tcl name of an uicontrol, for assigning properties beyond those supported by uicontrol: get(handle,"path").
//example: achieve a vertical slider figure(1); h=uicontrol("style","slider","position",[10 150 150 30],"Min",1,"Max",10) TCL_EvalStr(get(h,"path")+" configure -orient vertical")
Binding hotkeys to uicontrols: seethis thread.
callbacks may perform asynchronously, thus a pushbutton is not always a successful way of stopping a script: Bug 1958 possibly. Beware of launching scripts from Scipad: Bug 2521
beware of using globals: Bug 1345