1

I am working on a App in MATLAB and I use the app design to build it. I have added a text area element in which I display messages to the user (similar use as the command window). In the the app the user can press buttons, which trigger functions to be executed and within those functions, I would like to be able to display some messages in this text area element.

This is an example of the code I use to display the text in this text area. I use a counter to add text in the list and simulate display without overwriting the previous messages.

% display execution message
app.nb_Text_stock                                   = app.nb_Text_stock + 1;
app.OutputStatusTextArea.Value(app.nb_Text_stock)   = {'My test here'};

As you can see, I need the app element. I could then pass it to the function all the way to the level where I need to display the text but my real question is, can I access the app element from within the function without passing it as an argument? The reason I want to do that is I have also a non-GUI version of the script where I would not be able to pass app as argument. So to make things simpler, I would like to have a parameters GUI = 1 or 0, and then based on that display either in the command window if GUI = 0 or in the text area in the GUI if GUI = 1. But for that I need to access the app element from inside my function. Is there a proper way to do that? Or do you have any suggestion for another approach for this problem?

Tulkkas
  • 973
  • 3
  • 10
  • 22

2 Answers2

0

If you have the handle of any graphical object, you can find pretty much any other object in the same figure using the .Parent and .Children fields (e.g. hObject.Parent.Parent.Children(3).String = 'foo'), optionally using ancestor. If you don't have any object handles, you can use findall, but this would require some means of identifying the correct figures/controls. This can be done using their Tag field, but it would require specifying it beforehand.

Dev-iL
  • 23,742
  • 7
  • 57
  • 99
0

You can store app object using setappdata, and get the object using getappdata:

  • Store app in startupFcn function (Code that executes after component creation):
    Add startupFcn by adding callback in "Code View".

    % Code that executes after component creation
    function startupFcn(app)
        % Store app in the root object (setappdata(groot, 'my_app', app) also works).
        setappdata(0, 'my_app', app)
    end
    
  • Read app object from any function:

    app = getappdata(0, 'my_app');
    

Note:

  • This is not a good coding practice.

What you supposed to do:

function NonGuiFun()
app = app1();
app.func();

What you are asking to do:

function NonGuiFun()

% Get app object (assuming `app` GUI is already open)
app = getappdata(0, 'my_app');

if ~isempty(app)
    app.func();
end

Here is the entire code of app1 class, that I used for testing (most of it is automatically generated):

classdef app1 < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure              matlab.ui.Figure
        Button                matlab.ui.control.StateButton
        TextAreaLabel         matlab.ui.control.Label
        OutputStatusTextArea  matlab.ui.control.TextArea
    end


    properties (Access = private)
        nb_Text_stock = 0; % Description
    end

    methods (Access = public)

        function results = func(app)
            app.nb_Text_stock = app.nb_Text_stock + 1;
            app.OutputStatusTextArea.Value(app.nb_Text_stock)   = {num2str(app.nb_Text_stock)};
        end
    end


    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)
            setappdata(0, 'my_app', app)
        end

        % Value changed function: Button
        function ButtonValueChanged(app, event)
            value = app.Button.Value;
            func(app);
        end

        % Close request function: UIFigure
        function UIFigureCloseRequest(app, event)
            setappdata(0, 'my_app', [])
            delete(app)

        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create UIFigure and hide until all components are created
            app.UIFigure = uifigure('Visible', 'off');
            app.UIFigure.Position = [100 100 640 480];
            app.UIFigure.Name = 'UI Figure';
            app.UIFigure.CloseRequestFcn = createCallbackFcn(app, @UIFigureCloseRequest, true);

            % Create Button
            app.Button = uibutton(app.UIFigure, 'state');
            app.Button.ValueChangedFcn = createCallbackFcn(app, @ButtonValueChanged, true);
            app.Button.Text = 'Button';
            app.Button.Position = [214 295 214 85];

            % Create TextAreaLabel
            app.TextAreaLabel = uilabel(app.UIFigure);
            app.TextAreaLabel.HorizontalAlignment = 'right';
            app.TextAreaLabel.Position = [210 211 56 22];
            app.TextAreaLabel.Text = 'Text Area';

            % Create OutputStatusTextArea
            app.OutputStatusTextArea = uitextarea(app.UIFigure);
            app.OutputStatusTextArea.Position = [281 175 150 60];

            % Show the figure after all components are created
            app.UIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = app1

            % Create UIFigure and 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

Note that UIFigureCloseRequest executes: setappdata(0, 'my_app', []).

Rotem
  • 30,366
  • 4
  • 32
  • 65
  • This method would still require that I pass the app object in argument in order to call func(app) isn it? – Tulkkas Feb 25 '20 at 15:54
  • No, you can get `app` using `app = getappdata(0, 'my_app');` without passing it as an argument. – Rotem Feb 25 '20 at 15:57