MATLAB: Close a waitbar of a GUI from a function

breakfor loopleaveloopsmatlab guiquitreturnwaitbarwhile loop

Hello all,
I made a waitbar with a cancel button that appears when I press a push button on my GUI. This same push button makes another function runs. From inside this function I update the status of the waitbar.
My question is, if I press the cancel of the waitbar I want the function to stop running, and the user will be back to the main GUI.
This is the callback of the push button, indutancia is the function:
% --- Executes on button press in simular.
function simular_Callback(hObject, eventdata, handles)
% hObject handle to simular (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.f = waitbar(0,'Aguardando inicializaĆ§Ć£o...','Name','Aguarde por favor...',...
'CreateCancelBtn','setappdata(gcbf,''canceling'',1)');
setappdata(handles.f,'canceling',0);
indutancia(handles, hObject);
delete(handles.f);
Inside the function, there are lots of for loops.
The code below shows the loops where I update the waitbar. The problem is, when I press the Cancel button, the whole code freezes, and the waitbar continues there.
num_ind_inv = length(vetor_2n_inv);
for k = 1 : num_ind_inv
L_inv = 1e3 * vetor_2n_inv{k}(3); % [mH]

Fsw = vetor_2n_inv{k}(2);
Delta_i = vetor_2n_inv{k}(1);
for material = 1 : 5
proj_indutor(Fsw, L_inv, V, Pout, Vdc, material, Delta_i, I_out_p, I_out_ef);
prog_aux = prog_aux + 1;
prog = prog + prog_aux / total;
if getappdata(f,'canceling')
break
end
waitbar(prog,f,sprintf('%i de %i', prog_aux,total));
end
end
[...]
num_ind_ret = length(vetor_3n_ret);
for k = 1 : num_ind_ret
L_ret = 1e3 * vetor_3n_ret{k}(3); % [mH]
Fsw = vetor_3n_ret{k}(2);
Delta_i = vetor_3n_ret{k}(1);
for material = 1 : 5
proj_indutor(Fsw, L_ret, V, Pout, Vdc, material, Delta_i, I_in_p, I_in_ef);
prog_aux = prog_aux + 1;
prog = prog + prog_aux / total;
if getappdata(f,'canceling')
break
end
waitbar(prog,f,'Aguarde por favor...');
end
end
Thank you for the help!

Best Answer

The break command terminates execution of a while-loop or a for-loop. In nested loops, break exits only from the loop in which it occurs.
To demonstrate this, run this for-loops. You'll notice that the fprintf command only executes when i==1 but the final i value continue to 5.
clc()
for i = 1:5
for j = 1:3
if i > 1
break
else
fprintf('i = %d\n',i)
end
end
end
fprintf('final_i = %d\n',i)
Option 1: use while loops
Set up the while-loop so one of two conditions will end the loop: 1) when num_ind_inv is reached or 2) when the cancel button is pressed.
k = 1;
cancelled = getappdata(f,'canceling');
while k <= num_ind_inv && ~cancelled
. . .
k = k + 1;
cancelled = getappdata(f,'canceling');
end
Option 2: conditionally shortcircuit the for-loops
Set a condition at the top of each for-loop
for k = 1 : num_ind_inv
% move this to the top of each loop
if getappdata(f,'canceling')
break % Skip to next iteration

end
for material = 1 : 5
if getappdata(f,'canceling')
break % Skip to next iteration
end
% [code that executes if not cancelled]

end
% [code that executes if not cancelled]
end
In both cases, if you are storing variables in a loop, be sure to pre-allocate the variables prior to the loops so each element has a default vaue such as NaN, missing, empty, or some other meaningful flag to indicate missing data.
Option 3: leave the function entirely
...by using the return command which returns control to the invoking program or command prompt. In your case, after return is executed within the indutancia function, control will be returned to whatever function/script called indutancia() or the command window.
Related Question