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


Недавно опубликованная статьяв 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 6

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

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

Проверка страницы в Firefox

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

Поскольку мы хотим манипулировать выравниванием текста, мы гуглим некоторые релевантные ключевые слова и находим свойство CSS text-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