Search code examples
matlabuser-interfacecheckboxhandles

MATLAB: How to pass data between 2 GUIs using the findobj-Function?


i am new to creating GUIs with Matlab. I have one MainGui from which i open a Subgui so that the user can click checkboxes. After clicking the okay-Button my Subgui closes and one sees the MainGui-surface again.

How can i access the clickbutton value without using getappdata and setappdata and instead doing it with findobj-function which when it works is far easier for me.

So i am in the MainGui code and i look for the Subgui with

 hGui = findobj('Tag','Subgui');

where 'Subgui' is the value of the Tag property of the SubGUI. Handles visibility is on for both!!

    % get control handles for this GUI
    handlesSubgui = guidata(hGui);

    % now read the data from the checkbox
    checkValue = get(handlesSubgui.checkbox1,'Value');

Why doesnt it work? i set the correct Tags and handle visilility is on but i get

hGui =

     Empty matrix: 0-by-1

!?

Has anyone an idea? i would be glad to get help! Best regards, John


Solution

  • One option to consider for a case like this is to initialize a small GUI inside your button callback. To illustrate, I'll set up a little programmatic GUI:

    function testcode
    res = get(0,'ScreenSize');
    figdim = [300 300]; % Figure size, pixels
    
    h.mainfig = figure( ...
        'Units', 'Pixels', ...
        'Position', [(res(3) - figdim(1))/2 (res(4) - figdim(2))/2 figdim(1) figdim(2)], ...
        'Name', 'This is the Main GUI', ...
        'Resize', 'off', ...
        'DockControls', 'off', ...
        'NumberTitle', 'off', ...
        'MenuBar', 'none', ...
        'Toolbar', 'none' ...
        );
    
    h.subGUIbutton = uicontrol( ...
        'Parent', h.mainfig, ...
        'Units', 'Normalized', ...
        'Position', [0.25 0.6 0.5 0.3], ...
        'String', 'Open Checkbox GUI' ...
        );
    
    h.displaydatabutton = uicontrol( ...
        'Parent', h.mainfig, ...
        'Units', 'Normalized', ...
        'Position', [0.25 0.1 0.5 0.3], ...
        'String', 'Display Checkbox Selections' ...
        );
    
    % Requires R2014b or newer, otherwise we'll have to use set
    try
        h.subGUIbutton.Callback = {@checkboxGUI, h};
        h.displaydatabutton.Callback = {@displaydata, h};
    catch
        set(h.subGUIbutton, 'Callback', {@checkboxGUI, h});
        set(h.displaydatabutton, 'Callback', {@displaydata, h});
    end
    

    And our callbacks will be structured like this:

    function checkboxGUI(~, ~, handles)
    res = get(0,'ScreenSize');
    figdim = [200 200]; % Figure size, pixels
    h2.mainfig = figure( ...
        'Units', 'Pixels', ...
        'Position', [(res(3) - figdim(1))/2 (res(4) - figdim(2))/2 figdim(1) figdim(2)], ...
        'Name', 'This is the Sub GUI', ...
        'Resize', 'off', ...
        'DockControls', 'off', ...
        'NumberTitle', 'off', ...
        'MenuBar', 'none', ...
        'Toolbar', 'none' ...
        );
    
    % Build some checkboxes
    for ii = 1:4
        h2.checkbox(ii) = uicontrol( ...
            'Parent', h2.mainfig, ...
            'Style', 'checkbox', ...
            'Units', 'Normalized', ...
            'Position', [0.25 (1 - ii*0.15) 0.5 0.1], ...
            'String', sprintf('Checkbox #%u', ii) ...
            );
    end
    
    h2.closebutton = uicontrol( ...
        'Parent', h2.mainfig, ...
        'Style', 'pushbutton', ...
        'Units', 'Normalized', ...
        'Position', [0.25 0.15 0.5 0.1], ...
        'String', 'Accept Changes', ...
        'Callback', {@closecheckbox} ...
        );
    
        function closecheckbox(~, ~)
            % requires R2014b or newer for dot notation
            try
                test = find([h2.checkbox(:).Value]); % Returns ID of checked boxes
            catch
                test = find(cell2mat(get(h2.checkbox(:), 'Value'))'); % Returns ID of checked boxes
            setappdata(handles.mainfig, 'BoxesChecked', test);
            close(h2.mainfig);
        end
    
    waitfor(h2.mainfig); % Wait for user to close the checkbox GUI
    end
    
    function displaydata(~, ~, handles)
    BoxesChecked = getappdata(handles.mainfig, 'BoxesChecked');
    
    if isempty(BoxesChecked)
        fprintf('No boxes celected\n');
    else
        fprintf('User selected box: %d\n', BoxesChecked);
    end
    end
    

    Note that I've used a nested function for readability. In this simple example we have two buttons in our main GUI, a button to open the user prompt and then a display button. When the user opens the checkbox prompt, execution of all GUI commands pauses until the prompt is closed. When the display button is clicked, we get the checked values from the app data and print them to the command window.