如何将焦点设置在 uifigure 中的特定元素上?
How to set the focus on a specific element in a uifigure?
我有一个向用户显示 SVG 图像的应用程序,他们需要根据显示的内容填写两个编辑字段。由于该过程需要重复多次,因此我得出结论,如果用户交互只需要键盘,那么速度和效率最好。为此,我必须确保几件事:
- 人物在焦点上。
- Tab ⭾ 以正确的顺序循环元素(edit1 → edit2 → 按钮)。
- 每当刷新图像时,正确的编辑字段就会聚焦。
第 1st 要求可以通过切换图形可见性来满足,如 所述。
2nd 要求也很容易实现,只需要按特定顺序定义图形元素,如 here (for uifigures) and here(对于图形)所讨论的那样。
我的困难在于第 3rd 要求,具体来说 - 我不知道如何确保所需的编辑字段获得焦点需要的时候。请参考以下class,其中focusControl
方法只是一个占位符。
classdef SVGAxisLimit < handle
properties (GetAccess = private, SetAccess = immutable)
hF (1,1)
hI (1,1) matlab.ui.control.Image
hLL (1,1) matlab.ui.control.NumericEditField
hRL (1,1) matlab.ui.control.NumericEditField
hDone (1,1) matlab.ui.control.Button
end
methods
function obj = SVGAxisLimit()
% Create figure:
hF = uifigure('WindowState','maximized','Color','w'); drawnow;
% Create image:
hI = uiimage(hF, 'Position', [1,100,hF.Position(3),hF.Position(4)-100]);
% Create controls:
uilabel(hF, 'HorizontalAlignment', 'left', 'Position', [600 20 150 42],...
'Text', 'Left Limit:', 'FontSize', 22);
% Create LeftLimitEditField
hLL = uieditfield(hF, 'numeric', 'Position', [710 20 80 42], 'FontSize', 22);
% Create RightLimitEditFieldLabel
uilabel(hF, 'HorizontalAlignment', 'left', 'Position', [900 20 150 42],...
'Text', 'Right Limit:', 'FontSize', 22);
% Create RightLimitEditField
hRL = uieditfield(hF, 'numeric', 'Position', [1025 20 80 42], 'FontSize', 22);
% Create DoneButton
hDone = uibutton(hF, 'push', 'Text', 'Done', 'Position', [1200 20 80 42], ...
'FontWeight', 'bold', 'FontSize', 22, 'ButtonPushedFcn', @(varargin)uiresume(hF));
% Store handles:
obj.hF = hF;
obj.hI = hI;
obj.hLL = hLL;
obj.hRL = hRL;
obj.hDone = hDone;
end
end
methods (Access = public)
function [realLims] = showSVG(salObj, svgPath)
salObj.hI.ImageSource = svgPath;
% Focus left edit field
SVGAxisLimit.focusControl(salObj.hLL);
% Wait for a click on "done"
uiwait(salObj.hF);
% When resume, capture values:
realLims = [salObj.hLL.Value, salObj.hRL.Value];
end
end
methods (Access = private, Static = true)
function [] = focusControl(hObject)
% hObject is the handle of the uicontrol which needs to be focused
% ???
end
end
end
我正在使用 MATLAB R2020a。
P.S。
我决定为此使用 uifigures,因为它们 uiimage
component natively supports the presentation of SVGs (although 避免了这个组件存在)。
看到UIFigure
大部分是网页,原来是.focus()
and .select()
can be useful here. The only difficulty that remains is finding some way to refer to the web element (widget) in question. Fortunately, the HTML elements corresponding to edit fields in R2020a are identified by a unique id
attribute, which makes it easy to refer to them using very simple DOM commands such as getElementById
的JavaScriptWebAPI方法。总结:
function [] = focusControl(hObject)
% hObject is the handle of the uicontrol which needs to be focused
[hWin, widgetID] = mlapptools.getWebElements(hObject);
hWin.executeJS(sprintf(...
'W = document.getElementById("%s"); W.focus(); W.select();', widgetID.ID_val));
end
哪里可以找到 mlapptools
here(披露:我是该实用程序的合著者)。
我有一个向用户显示 SVG 图像的应用程序,他们需要根据显示的内容填写两个编辑字段。由于该过程需要重复多次,因此我得出结论,如果用户交互只需要键盘,那么速度和效率最好。为此,我必须确保几件事:
- 人物在焦点上。
- Tab ⭾ 以正确的顺序循环元素(edit1 → edit2 → 按钮)。
- 每当刷新图像时,正确的编辑字段就会聚焦。
第 1st 要求可以通过切换图形可见性来满足,如
2nd 要求也很容易实现,只需要按特定顺序定义图形元素,如 here (for uifigures) and here(对于图形)所讨论的那样。
我的困难在于第 3rd 要求,具体来说 - 我不知道如何确保所需的编辑字段获得焦点需要的时候。请参考以下class,其中focusControl
方法只是一个占位符。
classdef SVGAxisLimit < handle
properties (GetAccess = private, SetAccess = immutable)
hF (1,1)
hI (1,1) matlab.ui.control.Image
hLL (1,1) matlab.ui.control.NumericEditField
hRL (1,1) matlab.ui.control.NumericEditField
hDone (1,1) matlab.ui.control.Button
end
methods
function obj = SVGAxisLimit()
% Create figure:
hF = uifigure('WindowState','maximized','Color','w'); drawnow;
% Create image:
hI = uiimage(hF, 'Position', [1,100,hF.Position(3),hF.Position(4)-100]);
% Create controls:
uilabel(hF, 'HorizontalAlignment', 'left', 'Position', [600 20 150 42],...
'Text', 'Left Limit:', 'FontSize', 22);
% Create LeftLimitEditField
hLL = uieditfield(hF, 'numeric', 'Position', [710 20 80 42], 'FontSize', 22);
% Create RightLimitEditFieldLabel
uilabel(hF, 'HorizontalAlignment', 'left', 'Position', [900 20 150 42],...
'Text', 'Right Limit:', 'FontSize', 22);
% Create RightLimitEditField
hRL = uieditfield(hF, 'numeric', 'Position', [1025 20 80 42], 'FontSize', 22);
% Create DoneButton
hDone = uibutton(hF, 'push', 'Text', 'Done', 'Position', [1200 20 80 42], ...
'FontWeight', 'bold', 'FontSize', 22, 'ButtonPushedFcn', @(varargin)uiresume(hF));
% Store handles:
obj.hF = hF;
obj.hI = hI;
obj.hLL = hLL;
obj.hRL = hRL;
obj.hDone = hDone;
end
end
methods (Access = public)
function [realLims] = showSVG(salObj, svgPath)
salObj.hI.ImageSource = svgPath;
% Focus left edit field
SVGAxisLimit.focusControl(salObj.hLL);
% Wait for a click on "done"
uiwait(salObj.hF);
% When resume, capture values:
realLims = [salObj.hLL.Value, salObj.hRL.Value];
end
end
methods (Access = private, Static = true)
function [] = focusControl(hObject)
% hObject is the handle of the uicontrol which needs to be focused
% ???
end
end
end
我正在使用 MATLAB R2020a。
P.S。我决定为此使用 uifigures,因为它们 uiimage
component natively supports the presentation of SVGs (although
看到UIFigure
大部分是网页,原来是.focus()
and .select()
can be useful here. The only difficulty that remains is finding some way to refer to the web element (widget) in question. Fortunately, the HTML elements corresponding to edit fields in R2020a are identified by a unique id
attribute, which makes it easy to refer to them using very simple DOM commands such as getElementById
的JavaScriptWebAPI方法。总结:
function [] = focusControl(hObject)
% hObject is the handle of the uicontrol which needs to be focused
[hWin, widgetID] = mlapptools.getWebElements(hObject);
hWin.executeJS(sprintf(...
'W = document.getElementById("%s"); W.focus(); W.select();', widgetID.ID_val));
end
哪里可以找到 mlapptools
here(披露:我是该实用程序的合著者)。