toc vector in GUI Matlab - matlab

I have created a GUI, using GUIDE. I have added pushbuttons which perform a task. The start button, plots a graph and plays a wavefile that I have assigned to it. in the start button I have added as well a 'tic'.
on the other side of the GUI is have another button, the save button. The function of that button is to save to a vector the exact time that I push the button. The code that I have used saves only the last instance, while I want to be able to see all of the elements of that vector.
handles.counter.push(handles.count + 1)
handles.sfront(size(handles.counter)) = toc
Is there a way to save all of the instances to the sfront vector?
Thank you in advance!

You have to store your handles every time before the end of callback function.
Use GUIDATA:
guidata(hObject,handles)

To add a new element to the end of a vector use:
handles.sfront(end+1) = toc;
Then call guidata(hObject,handles) to store the updated version of handles.
I can't recreate your entire GUI here, but here's an example of storing multiple toc outputs in a vector. Takes about 10 seconds to run:
tic
tocList = [];
for i = 1:5
tocList(end+1) = toc;
pause(2)
end

Related

GUI wait for user input and do something if time runs out

I am working with a script that takes user input. I want the user to answer on the input within 4 seconds otherwise the code shall do something (right now without using a GUI). What I have done so far is to start a tic and prompt a input testInput = input('Enter the number: '); Meanwhile the prompt is open (waiting for input) I am checking if time has not runed out:
elapsed_time = toc;
if elapsed_time > 4
%do something
end
To the problem:
From what I have learned, there's no way to programmatically terminate a running command in MATLAB, or even let the code do something while the prompt is open. Therefore I can not check if 4 sec has passed before the user inputs something. I've read (here) that this might be possible to solve by using a GUI. I have although no idea how to implement this, since I am totally new.
So, would this be possible with a GUI? Because with the command window it is not.
I would really appreciate to see how something simple like this could look like as a GUI (just something very simple, a window with a input box):
%Start a time ticker
tic;
testInput = input('Enter the number: ');
elapsed_time = toc;
if elapsed_time > 4
%do something
end
Here is a small example of a custom GUI where the user should enter a number before a maximum time is reached. Please read some about callbacks, handles, figure options and uicontrol to better understand it.
Note that you might need to do som more fault handling of the input string (check that number is valid)
function EnterNumber()
% Create figure
inDlg = figure('NumberTitle','off','MenuBar','none','ToolBar','none');
% Create timer, set it to run TimerFcn after 4 s
maxTime = 4;
tH = timer('TimerFcn', {#closeFig inDlg}, 'StartDelay', maxTime);
% Create text and input box for number in figure
uicontrol(inDlg,...
'Style','Text','FontSize',14, ...
'String',sprintf('Please enter a number within %d seconds:', maxTime),...
'Units','Normalized','Position',[0.1 0.6 0.8 0.2]);
editBox = uicontrol(inDlg,...
'Style','Edit','Units','Normalized','Position',[0.1 0.5 0.8 0.2], ...
'FontSize',14,'Callback',#returnEditValue);
% Start timer
start(tH);
% Set focus on the edit box so a number could be entered instantly
uicontrol(editBox)
% Wait for figure to be closed (in any way)
waitfor(inDlg)
fprintf('Moving on ...\n');
% Callback function to save number
function returnEditValue(hObject,~)
% Get the number
number = str2double(get(hObject,'String'));
% Example of how to display the number
fprintf('The entered number is %d\n', number);
% Example of saving the number to workspace
assignin('base','number', number);
% Close figure
close(get(hObject,'Parent'));
% Calback function for timer timeout
function closeFig(~,~,figH)
% If figure exist, close it
if ishandle(figH)
close(figH)
fprintf('Too slow!\n')
end

How to retrieve data from one gui to another gui in matlab?

I have two GUIs. In the first gui I want to plot an input signal (ex: sine signal). My problem is, how can I plot back the same signal in the second GUI after I clicked the 'load' pushbutton in the second GUI? Can somebody help me? I really need help.
Here is some code to get you going about using setappdata and getappdata. This is very basic and there are things which I did not mention (eg using the handles structure or passing variables as input arguments to functions) but using setappdata and getappdata is a safe way to go.
I created 2 programmatic GUIs. The code looks a bit different than when GUIs are designed with GUIDE, but the principle is exactly the same. Take the time to examine it and understand what everything does; that's not too complicated.
Each GUI is composed of one pushbutton and an axes. In the 1st GUI (sine_signal) the sine wave is created and displayed. Pressing the pushbutton opens the 2nd GUI (gui_filtering) and calls setappdata. Once you press the pushbutton of that 2nd GUI, setappdata is called to fetch the data and plot it.
Here is the code for both GUIs. You can save them as .m files and press "run" in the sine_signal function.
1) sine_signal
function sine_signal
clear
clc
%// Create figure and uicontrols. Those will be created with GUIDE in your
%// case.
hFig_sine = figure('Position',[500 500 400 400],'Name','sine_signal');
axes('Position',[.1 .1 .8 .8]);
uicontrol('Style','push','Position',[10 370 120 20],'String','Open gui_filtering','Callback',#(s,e) Opengui_filt);
%// Create values and plot them.
xvalues = 1:100;
yvalues = sin(xvalues).*cos(xvalues);
plot(xvalues,yvalues);
%// Put the x and y values together in a single array.
AllValues = [xvalues;yvalues];
%// Use setappdata to associate "AllValues" with the root directory (0).
%// This way the variable is available from anywhere. You could also
%// associate the data with the GUI itself, using "hFig_sine" instead of "0".
setappdata(0,'AllValues',AllValues);
%// Callback of the pushbutton. In this case it is simply used to open the
%// 2nd GUI.
function Opengui_filt
gui_filtering
end
end
And
2) gui_filtering
function gui_filtering
%// Same as 1st GUI.
figure('Position',[1000 1000 400 400],'Name','sine_signal')
axes('Position',[.1 .1 .8 .8])
%// Pushbutton to load data
uicontrol('Style','push','Position',[10 370 100 20],'String','Load/plot data','Callback',#(s,e) LoadData);
%// Callback of the pushbutton
function LoadData
%// Use "getappdata" to retrieve the variable "AllValues".
AllValues = getappdata(0,'AllValues');
%// Plot the data
plot(AllValues(1,:),AllValues(2,:))
end
end
To show you the expected output, here are 3 screenshots obtained when:
1) You run the 1st GUI (sine signal):
2) After pressing the pushbutton to open the 2nd GUI:
3) After pressing the pushbutton of the 2nd GUI to load/display the data:
That's about it. Hope that helps!

How to determine the last time a user interacted with the matlab GUI?

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 ;)

Showing data on Matlab GUI which is continuously being updated in a separate Matlab function

I have a function in Matlab which is getting continuous sensor values from a hardware. It gives a flag when new values are available and we can update the variables holding these values. Following is a dummy function to mimic what this function is doing.
function example( )
% Example function to describe functionality of NatNetOptiTrack
% Hardware initialization,
% Retriving real time information continuously
for i = 1:100 %in real time this loop runs for ever
data = rand(3,6);
% Send the updated data to gui in each iteration
end
end
i have made a gui using guide as shown in the figure:
So the data to be displayed is a 3x6 matrix with columns corresponding to X Y Z Roll Pitch and Yaw values while rows correspond to Objects.
I want to show the continuously updated values from this function on the gui. Is there a way i can initialize gui inside my example function and update the output value by using the handles inside my loop. I tried copying the gui code inside the example function as a script, it was able to initialize but was not recognizing the handles.
Also i want to show the current values on command window when i press the button.
Thanks
If you launch the GUI and then run the function, you should be able to get the handles to the controls on the GUI provided that you make the GUI figure handle visible and set its tag/name to something appropriate. In GUIDE, open the Property Inspector for the GUI and set the HandleVisibility property to on, and the Tag property to MyGui (or some other name). Then in your example.m file do the following
function example( )
% Example function to describe functionality of NatNetOptiTrack
% get the handle of the GUI
hGui = findobj('Tag','MyGui');
if ~isempty(hGui)
% get the handles to the controls of the GUI
handles = guidata(hGui);
else
handles = [];
end
% Hardware initialization,
% Retriving real time information continuously
for i = 1:100 %in real time this loop runs for ever
data = rand(3,6);
% update the GUI controls
if ~isempty(handles)
% update the controls
% set(handles.yaw,…);
% etc.
end
% make sure that the GUI is refreshed with new content
drawnow();
end
end
An alternative is to copy the example function code into your GUI - the hardware initializations could occur in the _OpeningFcn of your GUI and you could create a (periodic) timer to communicate with the hardware and get the data to display on the GUI.
As for displaying the current data when pressing the GUI button, you can easily do this by writing the contents of the GUI controls to the command line/window with fprintf. You will though need to make your example function interruptible so that the push button can interrupt that continuously running loop. You can do this by either adding a pause call (for a certain number of milliseconds) that gets executed at the end of each iteration of your loop, or just make use of the drawnow call from above (that is why I placed it outside of the if statement - so that it will be called on each iteration of your loop.
Try the above and see what happens!

MATLAB uitable row generation from user input

I've got a GUI in MATLAB which uses uitables for input. There are a fixed number columns, and each column has a very specific format which I have stored as a cell array, like so:
columnformat = {'text', 'numeric', {#doSomething, inputArg1}, {'Option1' 'Option2'}};
The number of rows is theoretically unlimited; the user could provide as many they like. The back-end is capable of handling arbitrarily many row inputs. Right now, I'm building a large uitable initially, and just assuming the user won't use it all.
Here's the question: I want to set up the table and associated code such that any time the user has selected the final row and presses enter, it creates a new row with the same format as the rest of the table.
I've tried many different approaches, including dynamically setting 'Data', and they all seem to break the custom formatting dictated by the cell array. I'm sure someone has done this before. Thanks for your help!
This solution works on GUI created using MATLAB GUIDE. I think it's true that MATLAB GUI shows odd behaviour, but I have seen most of the odd behaviour when debugging MATLAB callbacks using something like keyboard and not properly exiting from them using dbquit. So, my advice would be to stay away from using keyboard related commands for MATLAB GUIs created with GUIDE.
Now, back to solving your problem, follow these steps.
Step 1: Add this at the start of GUINAME__OpeningFcn:
handles.row_col_prev = [1 1];
Step 2: Click on the properties of the table in context and click on CellSelectionCallback. Thus, if the tag of the table is uitable1, it would create a function named - uitable1_CellSelectionCallback.
Assuming the figure of the GUI has the tag - addrows_figure
Add these in it:
%%// Detect the current key pressed
currentkey = get(handles.addrows_figure,'CurrentCharacter')
%%// Read in previous row-col combination
prev1 = handles.row_col_prev
%%// Read in current data. We need just the size of it though.
data1 = get(handles.uitable1,'Data');
%%// Main processing where a row is appended if return is pressed
if numel(prev1)~=0
if size(data1,1)==prev1(1) & currentkey==13 %%// currentkey==13 denotes carriage return in ascii
data1(end+1,:) = repmat({''},1,size(data1,2)); %%// Append empty row at the end
set(handles.uitable1,'Data',data1); %%// Save it back to GUI
end
end
%%// Save the current row-col combination for comparison in the next stage
%%// when selected cell changes because of pressing return
handles.row_col_prev = eventdata.Indices;
guidata(hObject, handles);
Hope this works out for you!
I couldn't think of a possibility to achieve what you want with a certain key, I think it would be possible with any key (KeyPressFcn). But I'd rather recommend to introduce a toolbar with a pushbutton:
h = figure(...
u = uitable(h, ...
set(u,'Tag','myTable')
tbar = uitoolbar(h);
uipushtool(tbar,'ClickedCallback',#addRow);
In your callback function then you need to get your data, add a row and write it back:
function addRow(~,~)
u = findobj(0,'Type','uitable','Tag','myTable');
data = get(u,'Data');
%// modify your data, add a row ...
set(src,'Data',data);
end
Sorry if everything is a little simple and untested, but a good answer would require a considerable effort, I don't have time for. The tag matlab-uitable can give you a lot of further ideas.