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.
Related
I'm attempting to create an animated plot in app designer. So i've got 2 variables u and x displayed on a graph in respect to time with a time slider and a button under it. I wanted to know if it was possible to have a loop always checking in the background if the button is showing '||' so that it would increment uiaxis to display the new set of u and x variable associated with a time increment. And it would keep looping until the button has been pressed or time is tmax where it will restart at 0 and stop incrementing. I've attempted it with a changing value callback however it doesn't seem to loop correctly.
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've written a Matlab program which counts different values when are particular button is pressed (so far just the numbers of "yes" and "no"). I'm trying to add a key listener so that when I press, for example, n on the keyboard the button is pressed, or the same actions are completed. I have tried the addListener and keyfunclistener functions but neither seems to be working.
Here is an example of the button:
no=uicontrol(h_fig,'callback',countnonerve,'position',[.65 .07 .1 .08],'string','No','style','pushbutton','Units','normalized');
Any suggestions? It would be very helpful I'm not familiar with MatLab
You could try using the KeyPressFcn property of the figure to record/capture individual key presses:
function keypress_Test
h = figure;
set(h,'KeyPressFcn',#keyPressCb);
function keyPressCb(src,evnt)
disp(['key pressed: ' evnt.Key]);
end
end
The above code can be pasted into a file and saved as keypress_Test.m. A figure is created and a callback assigned to the KeyPressFcn property.
It can be easily adapted for your GUI. Wherever you have access to the figure handles (probably the h_fig from above) just add set(h_fig,'KeyPressFcn',#keyPressCb); and paste the keyPressCb code into the same file.
If you are counting the number of times a certain key is pressed, then you will have to save this information somewhere..probably to the handles structure. Is that the case? If so, then you can easily access this from the callback
function keyPressCb(src,evnt)
disp(['key pressed: ' evnt.Key]);
% get the handles structure
handles = guidata(src);
if ~isempty(handles)
% do something here - increment count for evnt.Key
% save the updated count
guidata(src,handles);
end
end
Try it out and see what happens!
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
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