WindowKeyPressFcn executes after program interruption - matlab

I want to detect pressing of the key, when running matlab script in while loop. At the moment, I only want to display success, after pressing of the key. Unfortunately, the message is displayed only after program interruption (CTRL+C) not during program run. Here is the code:
% Init of callback
fig = gcf;
set(fig,'WindowKeyPressFcn',#keyPressCallback);
% keyPressCallback function
function keyPressCallback(source,eventdata)
keyPressed = eventdata.Key;
if strcmpi(keyPressed,'space')
disp('success');
end
end

You need to break the cycle of the script which is running so that Matlab will process other events, in essense your keypress. You can do that by adding a drawnow inside you while loop, the code below should give you enough to incorporate in your own:
fig = figure;
set(fig,'WindowKeyPressFcn',#(hFig,hEvent)fprintf('pressed key %s\n',hFig.CurrentKey) );
drawnow();
while true
if ~ishandle(fig); break; end
drawnow();
end

Related

Matlab - wait for the end of a callback function

I have a program using two timers. The first one allows me to communicate with a microcontroller every second and to update charts, and I use the second one to stop the program after 50 seconds if the user did not press stop button before. The problem is that I don’t know how to wait the end of the execution of the callback function of the first timer before ending the program. Sometimes, it stops in the middle of the first callback. I would like to avoid that, but I don’t know how. I tried to use “waitfor”, but it doesn’t work.
Here is a simple example with the same problem.
t = timer('ExecutionMode','fixedRate','Period', 1,'TimerFcn',#testWait);
fwait = figure('Visible','off');
start(t);
disp('start');
pause(5);
delete(fwait);
i=0;
while true
waitfor(fwait);
disp(int2str(i));
pause(0.05);
i = i + 1;
end
function testWait(src,event)
disp('before');
waitfor(evalin('base','fwait'));
disp('after');
assignin('base','fwait',figure('Visible','off'));
pause(1);
delete(evalin('base','fwait'));
end
Can someone help me please ! :)
You can try using uiwait and uiresume. Here's a code snippet for how to use it:
f = figure;
h = uicontrol('Position',[20 20 200 40],'String','Continue',...
'Callback','uiresume(gcbf)');
disp('This will print immediately');
uiwait(gcf);
disp('This will print after you click Continue');
close(f);

Exit matlab script once all figure windows are closed

I want to stop the execution of script once all window figures are closed (i.e when I manually finish closing each figure window with a click). I tried doing:
x = 1:10;
plot(x,x);
while ~isempty(findall(0,'Type','Figure'))
if isempty(findall(0,'Type','Figure'))
exit
else
continue
end
end
However with the above code i) no figure is displayed and ii) the loop never ends. So my question is: how can exit matlab execution once all figure windows are closed?
Instead of polling in a loop, you can use waitfor
f(1)=figure();
f(2)=figure();
x = 1:10;
plot(x,x);
drawnow;
for ix=1:numel(f)
waitfor(f(ix));
end
All you need is to update callbacks. For this purpose, use drawnow function inside your while loop. If you don't want to exit matlab, do not use exit. Your programm script will stop automatically after it will finish while loop:
x = 1:10;
plot(x,x);
while ~isempty(findall(0,'Type','Figure'))
drawnow
end

How to maximize a MATLAB GUI figure/window on startup?

I am currently evaluating GUIs in MATLAB and was wondering how to maximize a GUI window on startup, without the need for user interaction. The function I am using is stated hereafter and works fine if called on a button press, but calling it in the figure's OpeningFcn won't help.
http://www.mathworks.com/matlabcentral/fileexchange/25471-maximize
Any help on some startup section to place the function call, which is executed after the GUI window has been drawn? I searched for solutions related to startup code in MATLAB GUIs, but there were no results to date.
Thanks in advance for your efforts.
Since many people seem to be interested in this and there is still no public solution, I will describe my approach:
In the YourGUIName_OpeningFcn(hObject, eventdata, handles, varargin) function, append the following lines:
% Initialize a timer, which executes its callback once after one second
timer1 = timer('Period', 1, 'TasksToExecute', 1, ...
'ExecutionMode', 'fixedRate', ...
'StartDelay', 1);
% Set the callback function and declare GUI handle as parameter
timer1.TimerFcn = {#timer1_Callback, findobj('name', 'YourGUIName')};
timer1.StopFcn = #timer1_StopFcn;
start(timer1);
Declare the timer1_Callback and timer1_StopFcn functions:
%% timer1_Callback
% --- Executes after each timer event of timer1.
function timer1_Callback(obj, eventdata, handle)
% Maximize the GUI window
maximize(handle);
%% timer1_StopFcn
% --- Executes after timer stop event of timer1.
function timer1_StopFcn(obj, eventdata)
% Delete the timer object
delete(obj);
Declare the maximize function:
function maximize(hFig)
%MAXIMIZE: function which maximizes the figure withe the input handle
% Through integrated Java functionality, the input figure gets maximized
% depending on the current screen size.
if nargin < 1
hFig = gcf; % default: current figure
end
drawnow % required to avoid Java errors
jFig = get(handle(hFig), 'JavaFrame');
jFig.setMaximized(true);
end
Source of the maximize function:
http://www.mathworks.com/matlabcentral/fileexchange/25471-maximize

Abort current script on closing waitbar

I am using a waitbar like this:
h = waitbar(0,'Please wait...');
for i=1:100, % computation here %
waitbar(i/100)
% other operation here
end
close(h)
I would like to stop this script if the user close the waitbar (clicks the X of the window), without having to add a Cancel button.
Is there any way to do it?
You can test whether h is a valid handle, and exit the loop otherwise. Insert the following into your loop:
if ~ishandle(h)
break
end
You can try something like this :
if ishandle(h),
close(h);
% Your code here
else
%waitbar has been closed by the user
% call throw, return, or break
end
Hope it helps,

Matlab waitbar - close all doesn't work

I have some code which creates a waitbar:
if long_process %user specifies this true/false
h = waitbar(1/4, msg);
end
process(arg1,arg2);
Process is some function which does some plotting. If I do CTRL-C somewhere in process and I get left with a figure window I can just do close all and the figure disappears. However, the waitbar stays. I don't know how to make that thing close with 'close all'.
The reason this is bothering is because when I start debugging I often end up having 20+ waitbars open. 'close all' then comes in handy.
Actually, the close function gives you some more "forceful" options:
close all hidden
close all force
And if for some reason those don't work, one "nuclear" option you have is to delete all figures, including those with hidden handles, as suggested in the close and waitbar documentation:
set(0, 'ShowHiddenHandles', 'on');
delete(get(0, 'Children'));
You may find it easiest to create your own helper function to do this for you (and return the state of 'ShowHiddenHandles' to its default 'off' state) so you don't have as much to type:
function killEmAll
set(0, 'ShowHiddenHandles', 'on');
delete(get(0, 'Children'));
set(0, 'ShowHiddenHandles', 'off');
end
...And even a third option is to try and avoid the problem altogether (if the organization of your code allows it) by using onCleanup objects! If you run the following sample code, the waitbar should be automatically deleted for you when you CTRL-C out of the infinite loop:
function runprocess
h = waitbar(1/4, 'la la la...');
waitObject = onCleanup(#() delete(h));
process();
end
function process
i = 1;
while (i > 0)
i = i + 1;
end
end