GUI - Updating a figure pseudo real-time and stopping on mouse-click

Hi all,
On my GUI I'm attempting to write a callback function that runs a loop triggered by a button press and ends when the mouse is clicked. I have been able to code the trigger of a loop that 'continuously' updates a figure for a pre-specified number of iterations. Essentially, there is a callback function with a loop triggered at a button press on the GUI.
I would like to add code that prematurely ends the loop at a mouse press. I have looked at using the "WindowsbuttondownFcn" but could not successfully implement to end the loop. What approach should I take? Any help is greatly appreciated in advance! The current callback function is below:
function uipanel1_SelectionChangeFcn(hObject, eventdata, handles)
switch get(eventdata.NewValue,'Tag') % Get Tag of selected object.
case 'togglebutton1'
% Code for when radiobutton1 is selected.
axes(handles.axes1)
set (gcf, 'WindowButtonMotionFcn', @mouseMove)
y = 0;handles.stop = 0;
while y <15
y = y+1;
pause(0.2)
point = get(gcf,'currentpoint');
[point flag] = convertpoint(point(1),handles);
% Do not run if cursor outside of figure window
if flag == 0
updateplots2(handles,point)
end
end
End

Answers (3)

The WindowsbuttondownFcn seems like the correct approach. You need to do something in the WindowsbuttondownFcn callback which can then be checked from the uipanel1_SelectionChangeFcn loop.
From the command line or the function that builds your gui:
hfig = gcf;
set (hfig, 'WindowButtonDownFcn', @(src, evt)(setappdata(hfig, 'mouseclick', true)));
setappdata(hfig, 'mouseclick', false);
Then modify your while loop to include:
if getappdata(gcf, 'mouseclick')
break;
end

2 Comments

Thank you for the quick responses.
I am having trouble passing arguments from the function called by the WindowbuttondownFcn callback. I added the code
flag2 = set (gcf, 'WindowButtonDownFcn', @mouseclick)
and defined the function mouseclick as follows:
function [flag2] = mouseclick (hObject, handles)
flag2 = 1;
end
So that the new complete code looks like:
function uipanel1_SelectionChangeFcn(hObject, eventdata, handles)
% hObject handle to the selected object in uipanel1
% eventdata structure with the following fields (see UIBUTTONGROUP)
% EventName: string 'SelectionChanged' (read only)
% OldValue: handle of the previously selected object or empty if none was selected
% NewValue: handle of the currently selected object
% handles structure with handles and user data (see GUIDATA)
switch get(eventdata.NewValue,'Tag') % Get Tag of selected object.
case 'togglebutton1'
% Code for when radiobutton1 is selected.
flag2 = 0;
axes(handles.axes1)
set (gcf, 'WindowButtonMotionFcn', @mouseMove)
set(gcf, 'WindowButtonDownFcn', @mouseclick)
y = 0;handles.stop = 0;
while y <15
y = y+1;
pause(0.2)
fprintf('%d',flag2)
point = get(gcf,'currentpoint');
[point flag] = convertpoint(point(1),handles);
% Do not run if cursor outside of figure window
if flag == 0
updateplots2(handles,point)
end
end
case 'togglebutton2'
% Code for when radiobutton2 is selected.
disp('hi')
otherwise
% Code for when there is no match.
end
end
function [flag2] = mouseclick (hObject, handles)
flag2 = 1;
end
This is probably my lack of clear understanding of the function callback architecture, but I cannot use the variable 'flag2' outside of the 'mouseclick' function - This is what I'm attempting to use to 'break' my main loop upon a mouse click.
See my edit (which allows code formatting). I am passing the data about if a mouse click occurred via the application data of the figure.

Sign in to comment.

Instead of a mouse click (it might accidentally happen), you might want to consider adding a push button (or toggle button) on your GUI to stop it. I saw several posts recently. Jan Simon's answer in this post should provide sufficient leads.

2 Comments

The code is tracking the mouse position, so I would guess that moving the mouse to a button would screw things up.
Okay, then use the WindowsbuttondownFcn suggested by Daniel. I guess you can add a hidden toggle button (or anything else) in the GUI. In your WindowsbuttondownFcn callback, change the value. In your uipanel1_SelectionChangeFcn callback, combine that value check with your y<15 check in the condition for while-loop.

Sign in to comment.

With a little work you should be able to get your approach to work. A sexier and in my opinion better way to approach it is with a timer
doc timer
Basically you define a function that does:
function timercallback(src, evt, hfig, handles)
point = get(hfig, 'currentpoint');
[point, flag] = convertpoint(point(1), handles);
if flag == 0
updateplots2(handles, point)
end
end
then you build a timer
htimer = timer('ExecutionMode', 'fixedRate', 'Period', 0.2, 'StartDelay', 0.2, 'StartFcn', @(src, evt)timercallback(src, evt, gcf, handles), 'TasksToExecute', 15, 'TimerFcn', @(src, evt)timercallback(src, evt, gcf, handles));
Then your toggle button starts the timer and the WindowbuttondownFcn can stop the timer.

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Tags

Asked:

on 27 Aug 2011

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!