仅在编辑文本 MATLAB GUI 中输入数字
Numeric entry only in edit text MATLAB GUI
我在 MATLAB GUI 中有一个编辑文本。我希望用户只能写数字,每当他们写一个文本字符时,最后一个字符就会立即被删除。此外,我不知道将这段代码放在哪种函数中(回调、按键等)。
如果不求助于 Java,这是不可能的。那是因为 MATLAB 无法访问 uicontrol
的 typed 字符串;您只能访问其 current 字符串(即,在按 Enter 或更改焦点后)。
下面是一个不完美的解决方法。它使用两个相同的编辑框,一个在另一个之上,但最上面的框最初是隐藏的。可见编辑框KeyPressFcn
:
- 过滤数字按键
- 在具有全局存储的字符串中累积有效按键
- 将该字符串设置为不可见编辑框的当前字符串
- 使不可见的编辑框可见,从而遮挡您正在输入的内容
它的CallBack
函数然后
- 获取通常不可见框的字符串
- 将始终可见框的字符串设置为等于该字符串
- 再次隐藏通常不可见的框
这是实现(大量借鉴自 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
这工作得相当好,但它有一些缺点:
- 因为您在看不见的地方打字,所以光标被隐藏了
- 选择文本并按 backspace/delete 不起作用
- 资源效率不高
虽然可以使用 Java(请参阅 MATLAB 之神 Yair Altman 的 this post),但更简单和更常见的方法是接受用户正在输入无效输入,并且在 Callback
函数中只有 check/correct 它(即在按 Enter 之后)。
我在 MATLAB GUI 中有一个编辑文本。我希望用户只能写数字,每当他们写一个文本字符时,最后一个字符就会立即被删除。此外,我不知道将这段代码放在哪种函数中(回调、按键等)。
如果不求助于 Java,这是不可能的。那是因为 MATLAB 无法访问 uicontrol
的 typed 字符串;您只能访问其 current 字符串(即,在按 Enter 或更改焦点后)。
下面是一个不完美的解决方法。它使用两个相同的编辑框,一个在另一个之上,但最上面的框最初是隐藏的。可见编辑框KeyPressFcn
:
- 过滤数字按键
- 在具有全局存储的字符串中累积有效按键
- 将该字符串设置为不可见编辑框的当前字符串
- 使不可见的编辑框可见,从而遮挡您正在输入的内容
它的CallBack
函数然后
- 获取通常不可见框的字符串
- 将始终可见框的字符串设置为等于该字符串
- 再次隐藏通常不可见的框
这是实现(大量借鉴自 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
这工作得相当好,但它有一些缺点:
- 因为您在看不见的地方打字,所以光标被隐藏了
- 选择文本并按 backspace/delete 不起作用
- 资源效率不高
虽然可以使用 Java(请参阅 MATLAB 之神 Yair Altman 的 this post),但更简单和更常见的方法是接受用户正在输入无效输入,并且在 Callback
函数中只有 check/correct 它(即在按 Enter 之后)。