I have the following code in MATLAB, where the user has to enter the word "precipitations" letter by letter. After typing one letter, the user has to press Enter and the program checks, whether the typed letter was correct.
Now I would like to change the program, such that the user does not have to press Enter after typing a letter. Is there any operator or function in MATLAB which reacts to every pushed button, so one does not have to press Enter?
disp('Please enter "precipitations" without errors')
target=('precipitations');
n=size(target); n=n(2); % Characters number
for i=1:n;
YourInput(i)=input('','s');
if YourInput(i)==target(i)
disp('OK. Please, input the next symbol')
i=i+1;
else
disp('Error. Please try again.')
break
end
end
As far as I know, there is no built-in MATLAB function to do this. There is however a function getkey on MATLAB File Exchange.
You can download this function and change your code to use
YourInput(i) = getkey();
--
I of course wondered how this can be achieved, and it does the following: They create a new figure with a window size of 0,0 at position (1,1). You'll notice the new figure at the bottom left of the screen.
Then, a callback function KeypressFcn which is executed whenever a key is pressed, is created. The pressed key is saved in the UserData field of the figure, and returned as variable. The interesting parts of the function (and a minimal example) are:
fh = figure(...
'keypressfcn','set(gcbf,''Userdata'',double(get(gcbf,''Currentcharacter''))) ; uiresume ', ...
'position',[0 0 1 1] ...
);
uiwait ;
key = get(fh,'Userdata') ;
delete(fh) ;
Related
I load a data file and plot it in octave. But in the plot, I want to mark the periodic appearance of points on the plot. I used ginput() function for marking. But the problem I see is, if I mark a different point which was not supposed to mark and then immediately realise that i made mistake, now I want to delete my last marked point and then mark the correct point. I'm not able to do it. I found out that there is MATLAB function getpts() which does the same but octave version of getpts() is not there. Can anyone help me out please?
Example:
The sequence i want to mark is 1,2,3,4,5,6,7,8,9,10.
But accidently I mark 1,2,3,5 And realise that I did a mistake and then press delete button on the keyboard which deletes 5 and then I mark 4 and then 5.
While getpts is not implemented per se, producing a small function which gets inputs one by one via ginput and vets them to get the desired behaviour is fairly easy. E.g.
X = []; Y = [];
while true
[x, y, b] = ginput(1);
if b == 8 , X(end)=[]; Y(end)=[]; % backspace key pressed
elseif isempty(b), break; % enter key pressed
else , X(end+1)=x; Y(end+1)=y; % any other key
end
disp([X;Y]); fprintf('\n'); fflush(1); % Optional terminal output
end
This is a very flexible approach which allows you to modify and add functionality as you desire (e.g., add different markers based on specific key pressed, plot as you go, etc).
for i=1:100
fid=loadfigure(fnames(i).name)
pause(5)
end
The pause function is added to check figure. How to save iteration number (in fact, the file number) upon key press.
Use timer instead of pause with Java Robot. Use input for key presses in the command window.
input returns an empty matrix if Enter is pressed before pressing anything else. The below code waits for the user input for 5 seconds and if the user doesn't input anything, the Java Robot will press Enter and the code proceeds to the next iteration. If the input function returns something then it saves the iteration number before proceeding to the next iteration.
t = timer('StartDelay', 5, 'TimerFcn', #PressEnterButton);
ind=1;
for k=1:100
fid=loadfigure(fnames(i).name); %as it is from your code
start(t); %start the 5sec timer
if ~isempty(input('Wait for button press','s'));
iterNum{ind}= k; ind=ind+1;
end
stop(t); %stop the timer object
end
delete(t); %delete the timer object
function PressEnterButton(HObj, event)
%Function to press Enter button
import java.awt.*;
import java.awt.event.*;
r=Robot;
r.keyPress(KeyEvent.VK_ENTER);
r.keyRelease(KeyEvent.VK_ENTER);
end
P.S: The above code saves the iteration number when alphanumeric and/or special character keys are pressed.
I have a problem in Simulink, I have a variable "k" as constant Block (start Value k =1 ) and i want to increment "k" after each time I click on "the simulation button" untill "k" is 4 then it will be reset to 1 again.
i already try this (see atached Image 1), but in this case k it wil be so long inkremented until the Simulation time is finished (see atached Image 2) and that is not what i want.
enter image description here
enter image description here
i will apreciate any Help many thanks Jay
If you just want to update the value every time you run the simulation, your best option would be to put some code in the InitFcn callback.
This is a (optional) block of code which is run every time the model is initialized. To do this navigate File > Model Properties > Model Properties
Select the Callbacks tab, and then the InitFcn callback on the left. The following code will check if k exists yet in the workspace, and set it if not, and increment it if so. If you put it in the callback, and then set the constant block value to k you should get the behavior you want.
if ~exist('k', 'var')
k = 1;
else
k = k + 1;
end
if k>4
k = 1;
end
I have a function that displays a graph with some random elements. I want to have it so that when the user presses a certain key the function runs again, redistributing these random elements on the graph. What is the best way to go about doing this?
You can wrap this within a while loop and using ginput. Put your function call within a while loop, use ginput and poll for a keystroke, and while this key is being pushed, keep going. Something like this, assuming that your figure is open after each call to the function:
while true
%// Generate random data
%// Call function
%// Open figure
%// Get a key from the user
[~,~,b] = ginput(1);
%// If you push C or c, then continue
if b == 67 || b == 99
continue;
else %// Else, get out
break;
end
end
You want to set a key press callback for a figure you're using in a script by using the KeyPressFcn like so:
h = figure('KeyPressFcn',#testcallback);
Then place the following in a function testcallback.m file (you can also use a function handle):
function testcallback(hObject,callbackdata)
% Check to make sure key pressed is the escape key
if (strcmp(callbackdata.Key,'escape'))
% Do whatever processing you want
imshow(rand(40));
end
end
When you run the script, a figure will appear. Everytime you press escape, the function will fire:
using the input() function in MATLAB allows you to prompt and ask a user for input. You can use this function to prompt the user to enter a key, when this key is entered, your function can be called and re-run.
Documentation on this can be found on the Mathworks website
In a Matlab function, I would like to know the last time a user interacted with the Matlab GUI. By matlab GUI, I mean basically, a user typing in the command window, or in the editor.
The algorithm I wish to implement is essentially:
If it's been a while, the function will not grab focus, but operate in the background.
If the user has recently interacted, presumably he/she is interested "right now" in the results, and the function will grab focus.
This is a tough one ! Here is a proposition to do what you want with the command window only, based on this undocumented code and persitent variables.
I used two functions: CW_listen and CW_callback. A call to CW_listen (or CW_listen(true)) starts to listen to the command window, while a call to CW_listen(false) stops listening. While listening is on, any action performed on the command window trigs a call toCW_callback.
Here are the two functions:
function CW_listen(b)
% Default value
if ~exist('b', 'var'), b = true; end
% Get the reference handle to the Command Window text area
jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
try
cmdWin = jDesktop.getClient('Command Window');
jTextArea = cmdWin.getComponent(0).getViewport.getComponent(0);
catch
commandwindow;
jTextArea = jDesktop.getMainFrame.getFocusOwner;
end
% Instrument the text area's callback
if b
set(jTextArea,'CaretUpdateCallback',#CW_callback);
else
set(jTextArea,'CaretUpdateCallback',[]);
end
and
function CW_callback(varargin)
% Define a persistent variable
persistent last_call;
if isempty(last_call)
last_call = clock;
else
ts = clock;
Dt = etime(ts, last_call);
% Update the status bar
dt = javaMethod('getInstance', 'com.mathworks.mde.desk.MLDesktop');
if dt.hasMainFrame
dt.setStatusText(['Ellapsed time: ' num2str(Dt) 's']);
end
if Dt>5
fprintf('So long !\n');
last_call = ts;
else
% Do nothing
end
end
I also dislayed the ellapsed time in the status bar, it was useful for developping the code and adds a quite cool feature.
You can replace the time in seconds (here 5s) and the fprintf('So long !\n'); by any action of your choice. Be aware that inserting any kind of display outside of this if statement will result in an infinite display loop ...
For the moment I don't see how one could transpose this to the editor, but if you search in Undocumented Matlab you may find how to do it ;)