I have an edit text in a MATLAB GUI. I want the user to be able to write only numerals and whenever they write a text character, this last character is immediately deleted. Moreover, I don't know in which kind of function to put this code(callback, keypress, etc.).
This is impossible without resorting to Java. That is because MATLAB has no way to access a uicontrol
's typed string; you can only access its current string (i.e., after pressing Enter or changing focus).
Below is an imperfect workaround. It uses two identical edit boxes, one on top of the other, but the topmost box is initially hidden. The KeyPressFcn
of the visible edit box:
Its CallBack
function then
Here's the implementation (liberally borrowed from here):
function GUI_tst
% Create new GUI
G.fh = figure('menubar' , 'none',...
'units' , 'normalized', ...
'position', [.4 .4 .2 .2]);
% The actual edit box
G.eh1 = uicontrol('style' , 'edit',...
'units' , 'normalized', ...
'position' , [.1 .4 .8 .2],...
'string' , '',...
'KeyPressFcn', @kpr,...
'Callback' , @cll);
% The "fake" edit box
G.eh2 = copyobj(G.eh1, G.fh);
set(G.eh2, 'Visible', 'off');
% Its string (global)
G.eh_str = '';
guidata(G.fh, G);
end
% "Real" edit box' KeyPressFcn()
function kpr(~, evt)
if isempty(evt.Character)
return; end
G = guidata(gcbf);
% Occlude the "real" editbox with the "fake" one
set(G.eh2, 'visible', 'on');
% Accumulate global string if keys are numeric
if strcmp(evt.Key,'backspace')
G.eh_str = G.eh_str(1:end-1);
elseif isempty(evt.Modifier) && ...
any(evt.Character == char((0:9)+'0') )
G.eh_str = [G.eh_str evt.Character];
end
% Set & save new string
set(G.eh2, 'string', G.eh_str);
guidata(gcbf,G);
end
% "Real" edit box' CallBack()
function cll(~,~)
G = guidata(gcbf);
% Set the "real" box' string equal to the "fake" one's,
% and make the "fake" one invisible again
set(G.eh1, 'String', get(G.eh2, 'String'));
set(G.eh2, 'visible', 'off');
end
This works reasonably well, but it has some drawbacks:
Although it is possible using Java (see this post by MATLAB-god Yair Altman), the simpler and more common way to do it is to just accept that the user is typing invalid input, and only check/correct it in the Callback
function (i.e., after pressing Enter).