如何以比官方记录更多的方式自定义 App Designer 图形?
How to customize App Designer figures in more ways than officially documented?
最近发表的 article in UndocumentedMatlab, mentions that App Designer figures are actually web pages using the Dojo Toolkit。这意味着我们 可以 理论上直接操纵 HTML DOM 以实现某些 UI 自定义,否则这些自定义是不可用的。
下面是 App Designer 图窗定义的示例,出现在 App Designer 生成的 .m
文件中(在 MATLAB R2016a 上):
classdef domDemo < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure % UI Figure
LabelListBox matlab.ui.control.Label % List Box
ListBox matlab.ui.control.ListBox % Item 1, Item 2, Item 3, It...
end
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
end
end
% App initialization and construction
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure
app.UIFigure = uifigure;
app.UIFigure.Position = [100 100 260 147];
app.UIFigure.Name = 'UI Figure';
setAutoResize(app, app.UIFigure, true)
% Create LabelListBox
app.LabelListBox = uilabel(app.UIFigure);
app.LabelListBox.HorizontalAlignment = 'right';
app.LabelListBox.Position = [50 93 44 15];
app.LabelListBox.Text = 'List Box';
% Create ListBox
app.ListBox = uilistbox(app.UIFigure);
app.ListBox.Position = [109 36 100 74];
end
end
methods (Access = public)
% Construct app
function app = domDemo()
% Create and configure components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
...看起来像这样:
根据 uilistbox
(which redirects us to the page on Check Box Properties 的完整 属性 列表的文档),没有办法操纵例如列表项的文本对齐方式。如果是,
Question: How do we manipulate the ListBox
in the example app such that its contents become center-aligned, even though such a setting is not available to us?
为了成功完成这项任务,我们需要做几件事:
- 找到 HTML/CSS 所在的位置(这样我们就可以操纵它们)。
- 找到我们要编辑的 DOM 的哪个元素。
- 找出我们需要做出的改变。
- 找到使用 MATLAB 操作元素的方法。
逐步工作:
1。找出图形的 HTML/CSS 在哪里 stored/located
win = struct(struct(struct(app).UIFigure).Controller).Container.CEF;
URL = win.URL; % Needed only for testing in browser
2。找到我们需要编辑DOM的哪个元素
data_tag = char(struct(app.ListBox).Controller.ProxyView.PeerNode.getId);
使用浏览器验证:
3。找出我们需要做出的改变是什么
由于我们要操纵文本对齐方式,我们 google 一些相关关键字并找到 CSS text-align
property。那我们手动试试看是否真的有效:
4。找到一种使用 MATLAB
操作元素的方法
使用dojo.style
and dojo.query
:
win.executeJS(['dojo.style(dojo.query("[data-tag^=''' data_tag ''']")[0],"textAlign","center")']);
此答案的完整代码:
classdef domDemo < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure % UI Figure
LabelListBox matlab.ui.control.Label % List Box
ListBox matlab.ui.control.ListBox % Item 1, Item 2, Item 3, It...
end
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
% Customizations (aka "MAGIC GOES HERE"):
drawnow; rez = [];
warning off MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame
warning off MATLAB:structOnObject
while ~strcmp(rez,'"center"')
try
% 1. Get a handle to the webwindow:
win = struct(struct(struct(app).UIFigure).Controller).Container.CEF;
% 2. Find which element of the DOM we want to edit (as before):
data_tag = char(struct(app.ListBox).Controller.ProxyView.PeerNode.getId);
% 3. Manipulate the DOM via a JS command
rez = win.executeJS(['dojo.style(dojo.query("[data-tag^=''' ...
data_tag ''']")[0],"textAlign","center")']);
catch
pause(1); % Give the figure (webpage) some more time to load
end
end
end
end
% App initialization and construction
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure
app.UIFigure = uifigure;
app.UIFigure.Position = [100 100 260 147];
app.UIFigure.Name = 'UI Figure';
setAutoResize(app, app.UIFigure, true)
% Create LabelListBox
app.LabelListBox = uilabel(app.UIFigure);
app.LabelListBox.HorizontalAlignment = 'right';
app.LabelListBox.Position = [50 93 44 15];
app.LabelListBox.Text = 'List Box';
% Create ListBox
app.ListBox = uilistbox(app.UIFigure);
app.ListBox.Position = [109 36 100 74];
end
end
methods (Access = public)
% Construct app
function app = domDemo()
% Create and configure components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
最近发表的 article in UndocumentedMatlab, mentions that App Designer figures are actually web pages using the Dojo Toolkit。这意味着我们 可以 理论上直接操纵 HTML DOM 以实现某些 UI 自定义,否则这些自定义是不可用的。
下面是 App Designer 图窗定义的示例,出现在 App Designer 生成的 .m
文件中(在 MATLAB R2016a 上):
classdef domDemo < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure % UI Figure
LabelListBox matlab.ui.control.Label % List Box
ListBox matlab.ui.control.ListBox % Item 1, Item 2, Item 3, It...
end
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
end
end
% App initialization and construction
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure
app.UIFigure = uifigure;
app.UIFigure.Position = [100 100 260 147];
app.UIFigure.Name = 'UI Figure';
setAutoResize(app, app.UIFigure, true)
% Create LabelListBox
app.LabelListBox = uilabel(app.UIFigure);
app.LabelListBox.HorizontalAlignment = 'right';
app.LabelListBox.Position = [50 93 44 15];
app.LabelListBox.Text = 'List Box';
% Create ListBox
app.ListBox = uilistbox(app.UIFigure);
app.ListBox.Position = [109 36 100 74];
end
end
methods (Access = public)
% Construct app
function app = domDemo()
% Create and configure components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
...看起来像这样:
根据 uilistbox
(which redirects us to the page on Check Box Properties 的完整 属性 列表的文档),没有办法操纵例如列表项的文本对齐方式。如果是,
Question: How do we manipulate the
ListBox
in the example app such that its contents become center-aligned, even though such a setting is not available to us?
为了成功完成这项任务,我们需要做几件事:
- 找到 HTML/CSS 所在的位置(这样我们就可以操纵它们)。
- 找到我们要编辑的 DOM 的哪个元素。
- 找出我们需要做出的改变。
- 找到使用 MATLAB 操作元素的方法。
逐步工作:
1。找出图形的 HTML/CSS 在哪里 stored/located
win = struct(struct(struct(app).UIFigure).Controller).Container.CEF;
URL = win.URL; % Needed only for testing in browser
2。找到我们需要编辑DOM的哪个元素
data_tag = char(struct(app.ListBox).Controller.ProxyView.PeerNode.getId);
使用浏览器验证:
3。找出我们需要做出的改变是什么
由于我们要操纵文本对齐方式,我们 google 一些相关关键字并找到 CSS text-align
property。那我们手动试试看是否真的有效:
4。找到一种使用 MATLAB
操作元素的方法使用dojo.style
and dojo.query
:
win.executeJS(['dojo.style(dojo.query("[data-tag^=''' data_tag ''']")[0],"textAlign","center")']);
此答案的完整代码:
classdef domDemo < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure % UI Figure
LabelListBox matlab.ui.control.Label % List Box
ListBox matlab.ui.control.ListBox % Item 1, Item 2, Item 3, It...
end
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
% Customizations (aka "MAGIC GOES HERE"):
drawnow; rez = [];
warning off MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame
warning off MATLAB:structOnObject
while ~strcmp(rez,'"center"')
try
% 1. Get a handle to the webwindow:
win = struct(struct(struct(app).UIFigure).Controller).Container.CEF;
% 2. Find which element of the DOM we want to edit (as before):
data_tag = char(struct(app.ListBox).Controller.ProxyView.PeerNode.getId);
% 3. Manipulate the DOM via a JS command
rez = win.executeJS(['dojo.style(dojo.query("[data-tag^=''' ...
data_tag ''']")[0],"textAlign","center")']);
catch
pause(1); % Give the figure (webpage) some more time to load
end
end
end
end
% App initialization and construction
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure
app.UIFigure = uifigure;
app.UIFigure.Position = [100 100 260 147];
app.UIFigure.Name = 'UI Figure';
setAutoResize(app, app.UIFigure, true)
% Create LabelListBox
app.LabelListBox = uilabel(app.UIFigure);
app.LabelListBox.HorizontalAlignment = 'right';
app.LabelListBox.Position = [50 93 44 15];
app.LabelListBox.Text = 'List Box';
% Create ListBox
app.ListBox = uilistbox(app.UIFigure);
app.ListBox.Position = [109 36 100 74];
end
end
methods (Access = public)
% Construct app
function app = domDemo()
% Create and configure components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end