MATLAB Answers

0

'BusyAction' 'cancel' not working

Asked by Marc Lalancette on 20 Jul 2012
Hi,
I've been trying to prevent my GUI's users from clicking too quickly while a computation goes on in the background. I've set the BusyAction and Interruptible properties of a set of radio buttons and the uibuttongroup (and menu elements and push buttons) to 'cancel' and 'off' respectively, but the GUI still just queues the clicks. For the radiobutton group this is particularly bad because it lets users "check" and "uncheck" the radio buttons independently, causing weirdness once the queued callback(s) try to execute.
I've tried the demo that explains these 2 properties and it works fine, so why is it not working in my GUI? (it was created with GUIDE by the way) I've also seen other posts with alternate solutions, but I'd much prefer to get these properties working as they should. I'm just not seeing what the problem is.
Thanks!

  3 Comments

Jan
on 20 Jul 2012
Please post a minimal example which demonstrates your problem. Currently we can not see, what you have done, and suggesting a solution would be bold guessing.
I understand that would make it easier to test so I'll try to get to make a simple example later today, but I've explained what I've done as clear as I could: 2 radio button callbacks trigger lengthy calculations during which I want other clicks to be ignored ('BusyAction' set to 'Cancel'). But they are not ignored, they are queued.
Jan
on 23 Jul 2012
I do not believe that a core function of Matlab is damaged until I see the code and anybody can reproduce the problem. As long as you "cannot see what the problem is", it is unlikely that you have been able to explain it exactly in your message. And without an exact explanation, the creation of an answer must be based on guessing.
I'm convinced that your program contains a bug or conceptual error.

Sign in to comment.

2 Answers

Answer by Marc Lalancette on 23 Jul 2012
Edited by Marc Lalancette on 23 Jul 2012

I found a way to reproduce the other part of the problem. Replace the DoStuff function in the above code by a real calculation instead of a pause and now it queues instead of cancelling, both if you click on the other radiobutton or the pushbutton while the calculation is going on. Unfortunately, all this points to Matlab not actually being able to do what I wanted by using these properties (and at least this second problem looks like a bug to me). [Edit: actually, adding a "pause(0.1);" after the calculation seems to "fix" this part of the problem, and see the comment above for a somewhat obvious workaround to the other part.] Any comments?
function DoStuff(handles)
% Set mouse pointer as busy.
set(handles.figure1, 'Pointer', 'watch');
drawnow; % so the mouse pointer actually changes...
% Display something.
x = inv(rand(4000));
set(handles.text3, 'String', 'Done!');
% Reset mouse pointer.
set(handles.figure1, 'Pointer', 'arrow');
end

  0 Comments

Sign in to comment.


Answer by Marc Lalancette on 23 Jul 2012
Edited by Marc Lalancette on 23 Jul 2012

So unfortunately, my simple example does not act the same way, but it still demonstrates that you can change the radiobutton selection during the wait. Sorry for the long code, but since I don't see how to attach files, I had to convert the GUI to code.
By the way, I never said Matlab was to blame, I'm just looking for help. So now the problem is two fold, what we get here (selection change during the wait) and for some unknown reason (yet unreproduced), my original GUI does actually queue the extra clicks on the radio buttons as well as other controls. Going to look into it further, but again, any help is appreciated, which includes educated guesses.
function fig_hdl = BusyActionTest_build
% Initialize handles structure
handles = struct();
% Create all UI controls
build_gui();
% Assign function output
fig_hdl = handles.figure1;
% --------------------------------
function build_gui()
% Creation of all uicontrols
handles.figure1 = figure( ...
'Tag', 'figure1', ...
'Units', 'characters', ...
'Position', [103.8 46.1538461538462 90.2 15.4615384615385], ...
'Name', 'BusyActionTest', ...
'MenuBar', 'none', ...
'NumberTitle', 'off', ...
'Color', get(0,'DefaultUicontrolBackgroundColor'), ...
'Interruptible', 'off', 'BusyAction', 'cancel');
handles.uipanel2 = uibuttongroup( ...
'Parent', handles.figure1, ...
'Tag', 'uipanel2', ...
'UserData', zeros(1,0), ...
'Units', 'characters', ...
'Position', [3.8 1.46153846153846 50.2 12.3846153846154], ...
'Title', {'Button Group'}, ...
'SelectionChangeFcn', @uipanel2_SelectionChangeFcn, ...
'Interruptible', 'off', 'BusyAction', 'cancel');
handles.text3 = uicontrol( ...
'Parent', handles.uipanel2, ...
'Tag', 'text3', ...
'Style', 'text', ...
'Units', 'characters', ...
'Position', [7.8 1.46153846153845 36.2 1.61538461538462], ...
'String', '-');
handles.pushbutton1 = uicontrol( ...
'Parent', handles.figure1, ...
'Tag', 'pushbutton1', ...
'Style', 'pushbutton', ...
'Units', 'characters', ...
'Position', [59.8 10.6923076923077 26.2 2.38461538461538], ...
'String', {'Push Button'}, ...
'Callback', @pushbutton1_Callback, ...
'Interruptible', 'off', 'BusyAction', 'cancel');
handles.radiobutton5 = uicontrol( ...
'Parent', handles.uipanel2, ...
'Tag', 'radiobutton5', ...
'Style', 'radiobutton', ...
'Units', 'characters', ...
'Position', [5.8 7.46153846153848 17.4 1.76923076923077], ...
'String', {'Radio Button'}, ...
'Interruptible', 'off', 'BusyAction', 'cancel');
handles.radiobutton6 = uicontrol( ...
'Parent', handles.uipanel2, ...
'Tag', 'radiobutton6', ...
'Style', 'radiobutton', ...
'Units', 'characters', ...
'Position', [5.8 4.3846153846154 17.4 1.76923076923077], ...
'String', {'Radio Button'}, ...
'Interruptible', 'off', 'BusyAction', 'cancel');
end
% ----------------------------
function uipanel2_SelectionChangeFcn(hObject,evendata) %#ok<INUSD>
DoStuff(handles);
end
% ----------------------------
function pushbutton1_Callback(hObject,evendata) %#ok<INUSD>
set(handles.text3, 'String', 'The button was pushed!');
end
% ----------------------------
function DoStuff(handles)
% Set mouse pointer as busy.
set(handles.figure1, 'Pointer', 'watch');
drawnow; % so the mouse pointer actually changes...
% Display something.
for n = 1:5
set(handles.text3, 'String', ['Counting to 5: ', num2str(n, '%d')]);
pause(1);
end
set(handles.text3, 'String', '-');
% Reset mouse pointer.
set(handles.figure1, 'Pointer', 'arrow');
end
end

  1 Comment

A workaround to this part of the problem is to explicitely turn off/on the 'Enable' property of the two radio buttons before/after the call to DoStuff:
function uipanel2_SelectionChangeFcn(hObject,evendata)
set(handles.radiobutton5, 'Enable', 'off');
set(handles.radiobutton6, 'Enable', 'off');
DoStuff(handles);
set(handles.radiobutton5, 'Enable', 'on');
set(handles.radiobutton6, 'Enable', 'on');
end

Sign in to comment.