I created a GUI in Matlab and one of the buttons the user supposed to press at the beginning has a while loop in it. I am taking frames one by one in this while loop. My problem is that I want the user to be able to pause this process (not to stop completely), so I added a pause button and I am changing a flag as this button is pressed. I need to put a code inside this matlab that will pause the loop procedure as pause button is pressed once, and will continue to the loop process when pause button is pressed again. I tried
if flag==1
pause on;
else
pause off
end;
But I saw that "pause on;" does not pause a while loop. Is there a function or method that I can use? In addition, I want other buttons to be able to work when code is in pause mode; for example another button displays some words, so when in pause mode, if this display words button is pressed, it must display the words on screen. I tried using "waitfor" but it stopped everything and this display button didn't work.
I would appreciate any kind of help.
You probably want to use MATLAB's WAITFOR function to do this.
I think this may be what you are looking for
while flag == 1
% Get/process your user input here
% Finish checking user input
pause(1) %Check every second, can of course be reduced
end
Related
I have solved with my attempt but this is running only on "Debug mode" and not in "Normal Mode"
I have a Appdesigner GUI MATLAB. I have a button, and there is a loop like this
function RUN()
t=1:0.01:3600;
for i=1:numel(t)
y(1,i)=readValue();
plot(t(1:i),Tco(1:i));
pause(0.02)
end
end
function BUTTON_PRESS()
%BREAK FROM THAT LOOP
end
I want to break this loop when I click my button
My attempt(WORKS IN DEBUG MODE BUT NOT IN NORMAL)
2nd pic: In appdesigner inside a callback to a button "PLOT AND SIM" I passed a function main_plot_function()
1st pic: shows that main_plot_function Now "STOP BUTTON " appears but clicking on that it doesn't stops loop of plotting nor it print "BUTTON!!"
But none of them worked.
increasing the pause timer worked seamlessly to break the loop!
I want to detect how many times the user click spacebar in 5 seconds
Is there any good way to fix this problem?
Thanks
One way to easily read user inputs from the keyboard is to create a new figure and specify a KeyPressFcn callback function, which is executed automatically if any key is pressed.
Lets start off by creating a new figure. As we don't need the figure to display anything, let's make it as small as possible (i.e. 1 by 1 pixel) and place it at the lower corner of the display:
f = figure('Position',[0,0,1,1]);
Now we'll set the UserData property of the figure - which we will use as counter - to zero:
set(f,'UserData',0);
Now let's see what to do when a key is pressed: We can create a small callback function which checks if the pressed button was a space and increases the UserData counter if that was the case. We'll call that function isspace:
function isspace(hObject,callbackData)
if get(hObject,'CurrentCharacter') == ' '
set(hObject,'UserData',get(hObject,'UserData')+1);
end
end
Now simply set up the figure to use this function as KeyPressFcn by
set(f,'KeyPressFcn',#isspace);
This already counts the number of times space is pressed. The current value of the counter is read by
get(f,'UserData');
Now we need the time measurement. This can be done using a timer. We'll configure it to go off after 5 seconds and then assing a new value in the base workspace. For that we need a callback function timerCallback.m
function timerCallback(hObj,eventData)
assignin('base','nSpace',get(gcf,'UserData'));
delete(gcf);
stop(hObj);
delete(hObj);
end
t = timer('StartDelay',5,'TimerFcn',#timerCallback);
start(t);
And that's it: First create the figure, create the timer and after 5 seconds you get the number of key presses in the variable nSpace in your workspace and the window is closed.
I am new to Matlab so please bear with me.
So I created a two GUID GUI in which one generates a dynamic data and updates the plotting every second so I used pause(1) (which is continuous) and the second one takes the full data of the first GUI and plots it (opens on button press)
Is there a way where if I open the the second GUI the first GUI pauses and if and only if the second GUI is stopped the first GUI resumes its process?
Thanks in advance.
Update
Example:
gui1.m
function guie1()
for ii=1:100
c = magic(ii)
plot(c);
% a button at this point
% Some pause condition
drawnow;
end
so when I click on that button it would open a window (a new figure may be) so unless I close is the loop should be paused.
Here is the example:
run(fullfile(docroot,'techdoc','creating_guis','examples','callback_interrupt'));
Here is the link:
http://www.mathworks.com/help/matlab/creating_guis/callback-sequencing-and-interruption.html
Update:
Here:
http://blogs.mathworks.com/videos/2010/12/03/how-to-loop-until-a-button-is-pushed-in-matlab/
http://www.mathworks.com/matlabcentral/fileexchange/29618-spspj
I have a GUI with a uitable that the user can edit values in. I have a CellEditCallback function for that table that triggers and checks for input errors in the cells whenever a user presses enter while editing a cell or clicks outside the cell. That works great, but I also have a pushbutton that uses data from that table and my current problem is that when the pushbutton is clicked before any other spot outside the cell is clicked, or before enter is pressed for that matter, the pushbutton callback runs first, and after that callback finishes then the CellEditCallback runs. This is not ideal, as I need to check for errors before I use the data in my calculations. So, does anybody have any ideas on how to have the CellEditCallback function run first?
This code produces the problem I'm having:
% If you edit a cell and immediately click the button before clicking
% outside the cell or before hitting enter, the button's callback triggers
% before the CellEditCallback
function temp
% Create Figure
mainFig = figure('Units','characters',...
'Position',[45 5 200 50],...
'Renderer','opengl');
% Create uitable
tempData(1:10,1:5) = {''};
mainTable = uitable('parent',mainFig,...
'Units','characters',...
'Position',[5 25 180 20],...
'ColumnEditable',[true],...
'ColumnFormat',{'char'},...
'ColumnWidth',{150 150 150 150 150},...
'Data',tempData,...
'CellEditCallback',#enterDataCallback);
% Create Button
mainButton = uicontrol('Parent',mainFig,...
'Units','characters',...
'Position',[5 10 180 10],...
'Style','pushbutton',...
'String','Button',...
'Callback',#buttonCallback);
% Function for when cell data is edited
function enterDataCallback(src,evt)
disp('Cell Edited')
end
% Function for when a button is pressed
function buttonCallback(src,evt)
disp('Button Pressed')
end
end
Note 1: I did try using uiwait and waitfor but the problem isn't that the CellEditCallback function gets interrupted, it just is triggered after the pushbutton callback.
Note 2: That was a very basic description of what the functions do, but I do need the callbacks to trigger in that order because other things like flags and important variables in an outer function are set in the CellEditCallback so I need to have that callback run before the pushbutton one.
Thanks!
I contacted MATLAB Support about this problem and they told me that the callbacks occurring in that order is indeed an error and that it is fixed in the 2014b prerelease. However, to work around the error, I managed to do some messy coding to call the CellEditCallback from inside the Push Button Callback and then set a flag to make sure the CellEditCallback doesn't fire after the Push Button Callback is done.
I am writing a program in which at some point a graph is plotted and displayed on screen. The user then needs to press 'y' or 'n' to accept or reject the graph. My current solution uses the PsychToolbox (the actual solution doesn't need to), which includes a command called 'KbCheck' which checks at the time of calling the state of all the keyboard buttons. My code looks like this:
function [keyPressed] = waitForYesNoKeypress
keyPressed = 0; % set this to zero until we receive a sensible keypress
while keyPressed == 0 % hang the system until a response is given
[ keyIsDown, seconds, keyCode ] = KbCheck; % check for keypress
if find(keyCode) == 89 | find(keyCode) == 78 % 89 = 'y', 78 = 'n'
keyPressed = find(keyCode);
end
end
The problem is, that the system really does 'hang' until a key is pressed. Ideally, I would be able to scroll, zoom, and generally interact with the graphs that are plotted onscreen so that I can really decide whether or not I want to press 'y' or 'n'!
I have tried adding 'drawnow;' into the while loop above but that doesn't work: I still am unable to interact with the plotted graphs until after I've accepted or rejected them.
The solution doesn't have to use PsychToolbox; I assume there are plenty of other options out there?
Thanks
I'd use the input function:
a = input('Accept this graph (y/n)? ','s')
if strcmpi(a,'y')
...
else
...
end
Although admittedly it requires two keypresses (y then Enter) rather the one.
Wait for buttonpress opens up a figure, which may be unwanted. Use instead
pause('on');
pause;
which lets the user pause until a key is pressed.
Why not using waitforbuttonpress instead?
Documentation: http://www.mathworks.fr/help/techdoc/ref/waitforbuttonpress.html
You don't want to use waitforbuttonpress since it locks the figure gui (no zooming, panning etc).
pause can cause the command window to steal the focus from the figure.
The solution I find to work best is to open the figure with a null keyPressFcn in order to avoid focus problems:
figure('KeyPressFcn',#(obj,evt) 0);
and then wait for CurrentCharacter property change:
waitfor(gcf,'CurrentCharacter');
curChar=uint8(get(gcf,'CurrentCharacter'));
Wait for key press or mouse-button click:
Example:
w = waitforbuttonpress;
if w == 0
disp('Button click')
else
disp('Key press')
end
for more information visit:
http://www.mathworks.com/help/matlab/ref/waitforbuttonpress.html
The waitforbuttonpress command is good but is triggered by either a mouse click or a key press. If you want it to trigger only from a key press, you can use the following hack:
while ~waitforbuttonpress
end