Как настроить фигурки дизайнера приложений в большем количестве способов, чем официально задокументировано?
Недавно опубликованная статьяв UndocumentedMatlab , упоминает, чтоApp Designer рисунки на самом деле являются веб-страницами, использующимиDojo Toolkit . Это означает, что мымогли бы теоретически манипулировать HTML DOM напрямую для достижения определенных настроек пользовательского интерфейса, которые в противном случае недоступны.
Ниже приведен пример определения конструктора приложения рис, как представляется, в .m
файл, созданный с помощью конструктора приложения (на 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
(который перенаправляет нас на страницу на флажок свойства для полного списка свойств), не существует никакого способа манипулировать, например, выравнивание текста элементов списка. Если да, то
Вопрос : Как мы манипулируем
ListBox
в примере приложения таким образом, что его содержимое становится выровненным по центру, даже если такая настройка нам недоступна?
1 ответ:
Чтобы преуспеть в этой задаче, нам нужно несколько вещей:
- найдите, где расположены HTML / CSS (чтобы мы могли ими манипулировать).
- найдите, какой элемент DOM мы хотим отредактировать.
- найти то, что изменение, которое нужно сделать.
- найдите способ манипулировать элементом с помощью MATLAB.
Работа шаг за шагом:
1. Найдите, где хранятся HTML/CSS фигуры / 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. Найдите, какое изменение нам нужно сделать
Поскольку мы хотим манипулировать выравниванием текста, мы гуглим некоторые релевантные ключевые слова и находим свойство CSStext-align
. Затем мы пробуем его вручную, чтобы увидеть, действительно ли он работает:4. Найдите способ манипулировать элементом с помощью MATLAB
Использование
dojo.style
и еще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