Updating GUI handles when using callback

2.7k views Asked by At

I have a GUI made from GUIDE and I cannot figure out how to update a GUI handle when I call a callback in a callback. So for instance in the function which calls the function all I have is the following:

function start_ss_Callback(hObject, eventdata, handles)
% hObject    handle to start_ss (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of start_ss as text
%        str2double(get(hObject,'String')) returns contents of start_ss as a double
start_hh_Callback(hObject, eventdata, handles)

and in start_hh_Callback I have the code given below but my handles.plot_holds doesn't update regardless of the fact that I have guidata(hObject, handles). Is this because I'm using it as a function? If I just go through the start_hh_Callback itself not through start_ss_Callback, it updates. However, if I use it within a callback like start_ss_Callback it does not update.

I hope my question is clear, let me know if you need clarification.

function start_hh_Callback(hObject, eventdata, handles)
% hObject    handle to start_hh (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of start_hh as text
%        str2double(get(hObject,'String')) returns contents of start_hh as a double

axes(handles.axes1)
if isempty(handles.plot_holds)
    cla
    plot_button_Callback(hObject, eventdata, handles)
else
    % in the event the time is changed after more than 1 plot is held then
    % the additional plot times will be re evaluated for each parameter and
    % the new indicies will take into affect.
    myParams = get(handles.load_params_button,'string');
    mystartDD = str2num(get(handles.start_dd,'string'));
    mystartHH = str2num(get(handles.start_hh,'string'));
    mystartMM = str2num(get(handles.start_mm,'string'));
    mystartSS = str2num(get(handles.start_ss,'string'));

    myendDD = str2num(get(handles.end_dd,'string'));
    myendHH = str2num(get(handles.end_hh,'string'));
    myendMM = str2num(get(handles.end_mm,'string'));
    myendSS = str2num(get(handles.end_ss,'string'));

    startFromStart =  (mystartDD)*60*60*24 + (mystartHH-handles.startHour)*60*60 ...
        + (mystartMM-handles.startMinute)*60 + (mystartSS-handles.startSecond);
    endFromStart =  (myendDD)*60*60*24 + (myendHH-handles.startHour)*60*60 ...
        + (myendMM-handles.startMinute)*60 + (myendSS-handles.startSecond);

    iStart = find(handles.load.dataGST.(handles.myParams{handles.plot_holds(1,1)}).(handles.myPackets{handles.plot_holds(1,1)}{handles.plot_holds(1,2)}).Time > (startFromStart+handles.startTimeOffset),1);
    iEnd = find(handles.load.dataGST.(handles.myParams{handles.plot_holds(1,1)}).(handles.myPackets{handles.plot_holds(1,1)}{handles.plot_holds(1,2)}).Time > (endFromStart+handles.startTimeOffset),1);
    if isempty(iEnd)
        iEnd = length(handles.load.dataGST.(handles.myParams{handles.plot_holds(1,1)}).(handles.myPackets{handles.plot_holds(1,1)}{handles.plot_holds(1,2)}).Time);
    end

    cla
    hold off

    plot(handles.load.dataGST.(handles.myParams{handles.plot_holds(1,1)}).(handles.myPackets{handles.plot_holds(1,1)}{handles.plot_holds(1,2)}).Time(iStart:iEnd),...
        handles.load.dataGST.(handles.myParams{handles.plot_holds(1,1)}).(handles.myPackets{handles.plot_holds(1,1)}{handles.plot_holds(1,2)}).Data(iStart:iEnd))

    grid minor
    box on

    handles.plot_holds(1,3) = iStart;
    handles.plot_holds(1,4) = iEnd;

    if size(handles.plot_holds,1)>1
        hold all
        for ii = 2:size(handles.plot_holds)
            iStart = find(handles.load.dataGST.(handles.myParams{handles.plot_holds(ii,1)}).(handles.myPackets{handles.plot_holds(ii,1)}{handles.plot_holds(ii,2)}).Time > (startFromStart+handles.startTimeOffset),1);
            iEnd = find(handles.load.dataGST.(handles.myParams{handles.plot_holds(ii,1)}).(handles.myPackets{handles.plot_holds(ii,1)}{handles.plot_holds(ii,2)}).Time > (endFromStart+handles.startTimeOffset),1);
            if isempty(iEnd)
                iEnd = length(handles.load.dataGST.(handles.myParams{handles.plot_holds(ii,1)}).(handles.myPackets{handles.plot_holds(ii,1)}{handles.plot_holds(ii,2)}).Time);
            end
            plot(handles.load.dataGST.(handles.myParams{handles.plot_holds(ii,1)}).(handles.myPackets{handles.plot_holds(ii,1)}{handles.plot_holds(ii,2)}).Time(iStart:iEnd),...
                handles.load.dataGST.(handles.myParams{handles.plot_holds(ii,1)}).(handles.myPackets{handles.plot_holds(ii,1)}{handles.plot_holds(ii,2)}).Data(iStart:iEnd))
            handles.plot_holds(ii,3) = iStart;
            handles.plot_holds(ii,4) = iEnd;
        end
    end
end

legend(handles.myLegends{1:length(handles.myLegends)})

guidata(hObject, handles);
1

There are 1 answers

1
sebastian On BEST ANSWER

You'll have to load the handles again, after any handles-modifying function:

% this modifies and writes the handles to the guidata
start_hh_Callback(hObject, eventdata, handles);
% now read back the updated value
handles = guidata(hObject);

Alternatively you could also make handles the return value of you callback. Usually this will be ignored when it's really used as a callback and when used as a "normal" function it avoids the need to re-read from guidata. Your code could then look like this:

handles = start_hh_Callback(hObject, eventdata, handles);

with your callback redefined to:

function [handles] = start_hh_Callback(hObject, eventdata, handles)
...
end