Как настроить фигуры App Designer более подробно, чем официально задокументировано?

недавно опубликованном статья в UndocumentedMatlab отмечает, что Приложение Конструктор цифры на самом деле веб-страницы с помощью Dojo Toolkit. Это означает, что мы мог бы теоретически манипулировать HTML DOM непосредственно для достижения определенных настроек пользовательского интерфейса, которые в противном случае недоступны.

Ниже приведен пример определения фигуры дизайнера приложений, как показано в .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

...который выглядит так:

Example App Designer Figure

согласно документации uilistbox (который перенаправляет нас на страницу о Установите Флажок Свойства для полного списка свойств), нет никакого способа манипулировать, например, выравниванием текста элементов списка. Если так, то

вопрос: как мы манипулируем ListBox в примере приложения такое, что его содержимое становится центрированным, хотя такая настройка нам недоступна?

1 ответов


для того, чтобы преуспеть в этой задаче, нам потребуется несколько вещей:

  • найдите, где расположены HTML / CSS (чтобы мы могли ими манипулировать).
  • найдите, какой элемент DOM мы хотим отредактировать.
  • найдите, какие изменения нам нужно сделать.
  • найдите способ манипулировать элементом с помощью MATLAB.

шаг за шагом:

1. Найдите, где находятся HTML/CSS фигуры хранится/находится

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);

проверка с помощью браузера:

Inspecting the page in Firefox

3. Найдите, какие изменения нам нужно сделать

поскольку мы хотим манипулировать выравниванием текста, мы google некоторые соответствующие ключевые слова и найти в CSS text-align свойства. Затем мы попробуем это вручную, чтобы увидеть, действительно ли это работает:

enter image description here

4. Найдите способ манипулировать элементом с помощью MATLAB

используя dojo.style и dojo.query:

win.executeJS(['dojo.style(dojo.query("[data-tag^=''' data_tag ''']")[0],"textAlign","center")']);

Before and after


полный код для этого ответ:

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