How to access variables from base workspace within function?

I am a nested function inside a function and I am calling variables from base workspace. Note that guiel is in base workspace.

function callback(~,~)
    vars.dropheight = str2num(get(edit(2),'String'));
    vars.armradius = str2num(get(edit(1),'String'));
    kiddies = get(guiel.hAX(3),'Children'); 
    delete(kiddies);
    clear kiddies;
    set(guiel.tfPanel,'Visible','off','Position',cnst.tfPanelpos);
    set(guiel.hAX(1),'Position',cnst.axpos1);
    if ishandle(guiel.hAX(2)) 
    set(guiel.hAX(2),'Position',cnst.axpos2); 
    end 
    eval(get(guiel.hPB(4),'Callback'));
end

2 answers

  • answered 2017-11-15 04:04 Xiangrui Li

    The best way, in my opinion, is to store guiel into guidata.

    guidata(hFig, guiel); % hFig can be gcf for top figure
    

    and access it in callback by

    guiel = guidata(hFig);
    

    One of the alternatives is to pass the variable as input to callback by defining it as

    {@callback, guiel}
    

    The callback function definition will be

    function callback(~, ~, guiel)
    

    If you really hate these methods, a simple way is to define it as global in base and your callback. But this is something one tries to avoid for both performance and code maintainability consideration.

  • answered 2017-11-15 04:55 gnovice

    Best practices for GUI design are that you encapsulate your GUI and its operations in such a way that it never has to depend on the base workspace to function correctly. The reason? The user and other programs can modify anything in the base workspace, and can thus easily break your GUI.

    I give an example of a basic GUI setup using nested functions in this post. Here's a general skeleton for designing a GUI:

    function create_GUI()
    
      % Initialize data:
      data1 = ...;
      data2 = ...;
    
      % Create GUI:
      hFigure = figure;
      hObject1 = uicontrol(..., 'Callback', @callback1);
      hObject2 = uicontrol(..., 'Callback', @callback2);
      ....
    
      function callback1(~, ~)
        % Access any data or handles from above
        ...
      end
    
      function callback1(~, ~)
        % Access any data or handles from above
        ...
      end
    
    end
    

    The idea is that the main function creates all the GUI components, initializing all the needed data and object handles. The callbacks nested within the main function will have access to the data and handles as needed. I suggest designing your GUI like this, or using one of the other options listed here. This should alleviate some of your data access issues and make your GUI more robust.