0

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

john
  • 131
  • 2
  • 9
  • Is this a GUIDE GUI or a programmatic one? – sco1 Sep 14 '15 at 13:03
  • It is created with GUIDE! To what extend does it make a difference? – john Sep 14 '15 at 13:10
  • if `hGui` closes once you press the pushbutton I guess it makes sense that `MainGui` can't find it? – Benoit_11 Sep 14 '15 at 13:13
  • ahh okay Benoit_11, i thought i could find the figures object always, independent of the state, whether they are open or not! thank you, so i shall pass the data before closing the window with setappdata and getappdata! thanks, i was really confused!! – john Sep 14 '15 at 13:19
  • yep I think that would be a good idea :) Good luck! – Benoit_11 Sep 14 '15 at 13:28

1 Answers1

0

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.

sco1
  • 12,154
  • 5
  • 26
  • 48