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

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

Related

Matlab GUI Callback Start and Completion

Is there a general purpose way to determine when a Matlab GUI callback function begins and then has returned to the dispatcher?
I want to lock out user interaction while callbacks are running to completion and also show busy status while callbacks are running. Is there a dispatcher accessible where I can insert this code, or do I have to put it into every callback function.
I am aware of the modal waitbar but I want to avoid using that as much as possible. (They can't be killed gracefully.)
I suggest to add a wrapper function, that wraps all original UIControl callback functions.
The wrapper function does the following:
Locks (disables) all GUI UIControl objects.
Executes original callback function.
Enables all GUI UIControl after original callback returns.
You can also start a timer before original callback, and stop the timer when callback returns (the timer can simulate a wait bar using an image built int to the main GUI [image inside a small axes]).
Example (assuming GUI was created using guide tool):
% --- Executes just before untitled1 is made visible.
function untitled1_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to untitled1 (see VARARGIN)
% Choose default command line output for untitled1
handles.output = hObject;
%Add wrapper function to each UIControl callback.
A = findall(hObject.Parent, 'Type', 'UIControl');
for i = 1:length(A)
set(A(i), 'Callback', {#wrapper, A(i).Callback});
end
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes untitled1 wait for user response (see UIRESUME)
% uiwait(handles.figure1);
function wrapper(ObjH, EventData, origCallback)
disp('Do somthing before callback begins...');
%You can also start a timer.
%Disable all UIControl objects, before executing original callback
A = findall(ObjH.Parent, 'Type', 'UIControl');
for i = 1:length(A)
set(A(i), 'Enable', 'off');
end
%Execute original callback.
feval(origCallback, ObjH, EventData);
disp('Do somthing after callback ends...');
%You can also stop the timer.
%Enable all UIControl objects, after executing original callback
for i = 1:length(A)
set(A(i), 'Enable', 'on');
end
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
pause(1);
set(handles.pushbutton1, 'BackgroundColor', [rand(1,1), rand(1,1), rand(1,1)]);
You can generally lock user interaction with the waitfor command. It is designed to do exactly what you ask.
You can make your callback function update a handle property when it's finished, which can cause waitfor to exit. If that handle property you're updating also happens to hold the result of a tic / toc operation timing the duration of your callback function, then you kill two birds with one stone :)

How to call a callback function in a MATLAB gui from another gui?

I have two GUIs, made with GUIDE. I'm trying to call a pushbutton callback function in GUI1 from GUI2. Here is the code in GUI2
set(0,'showHiddenHandles','on');
hfig = gcf;
m_handles = guidata(hfig); % handles in GUI1
set(m_handles.show_status , 'String' , ...
[script sprintf('\n') s_response]); % this line works
set(m_handles.add_note , 'Enable' , 'off'); % this line also works
add_note_Callback(m_handles.add_note, eventdata, m_handles); % but this does not work!
Here is the error I get Undefined function 'add_note_Callback' for input arguments of type 'struct'. any help will be appreciated.
A possible solution can be the following.
Let's assume you have GUI 1 defined as follows:
GUI filename (the name of both the .m and .fig files) = master_gui
figure tag property defined as "figure1"
figure handlevisibility property set on
callback to be called from GUI 2: plot_something_Callback
Then from, say, a pushbutton in GUI 2 you want to call plot_something_Callback defined in GUI 1
So, in the GUI 2 pushbutton callback you can code:
% Get the GUI 1 obj
g_m=findobj('tag','figure1')
% Get GUI handles
gd_m=guidata(g_m);
% Call GUI 1 callback from GUI 2 callback
% master_gui('plot_something_Callback',gd_m.plot_something,[],g_m)
master_gui('plot_something_Callback',gd_m.plot_something,[],gd_m)
Notice, GUI 1 shall be open.
CODE MODIFIED
The last parameter in the call of GUI 1 callback is gd_m that is the GUI 1 handles
Sorry about the bug (the code I've originally posted worked because GUI 1 handles were not used in GUI 1 callback)
Hope this helps.

Callback functions in a loop in MATLAB GUI

This is a MATLAB GUI. And I have a while loop running. But while in the loop i need to use keyboard inputs which are a different callback. Is there a way or is it possible to execute that callback while it is in the loop?
Note: I am using GUIDE
Yes, this is possible. You just need to get the character data from the keypress callback to the callback that is in a loop. One way of doing this is via the figure guidata.
For example, if your loop is running from a button callback and you want to see a keypress on the figure you could use the following:
Button Callback
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
fig = get(hObject,'Parent');
for i=1:1000
pause(0.01);
% Get the latest guidata
handles = guidata(fig);
if isfield(handles,'KeyData' ) && ~isempty(handles.KeyData)
fprintf(1,'Pressed : %s\n', handles.KeyData.Character);
% Clear the keydata we have now handled.
handles.KeyData = [];
guidata(fig,handles);
end
end
Figure keypress callback
% --- Executes on key press with focus on figure1 and none of its controls.
function figure1_KeyPressFcn(hObject, eventdata, handles)
% Store the keypress event data for use in the looping callback
handles.KeyData = eventdata;
guidata(hObject,handles);

How to prevent a callback from being interrupted by a figure's close function?

Was wondering how the question in the title can be achieved. I have some callbacks that run from button presses. These callbacks, if interrupted by the figure close, will cause errors because the function seems to run, then gets interrupted by the close function which closes the figure, and then the callback seems to resume after the figure is closed.
If I set the button's 'Interruptible' property to 'on', it prevents other callbacks from interrupting it, but does not seem to work for the figure's close function. Another idea I had was to specify the 'closefunction' in the figuring's 'CloseRequestFcn' callback and then call drawnow to flush the eventqueue before deleting the figure but this did not work.
The last resort for me is to simply set the figure's 'CloseRequestFcn' to '' when running callbacks but this seems tedious. Is there a standard solution to accomplish this?
EDIT:
From matlab's documentation:
Note If the interrupting callback is a DeleteFcn or CreateFcn
callback or a figure's CloseRequest or ResizeFcn callback, it
interrupts an executing callback regardless of the value of that
object's Interruptible property. The interrupting callback starts
execution at the next drawnow, figure, getframe, pause, or waitfor
statement. A figure's WindowButtonDownFcn callback routine, or an
object's ButtonDownFcn or Callback routine are processed according to
the rules described above.
So it appears to be the case that the interruptible property doesn't effect the close function.
EDIT 2:
Ok, so I think I found a problem. It's really bizarre. I actually discovered from the matlab documentation that callbacks are only interruptible if they have the interruptible property set to on AND :
If there is a drawnow, figure, getframe, waitfor, or pause command in the running callback, then MATLAB executes the interrupting callbacks which are already in the queue and returns to finish execution of the current callback.
I don't use any of these functions explicitly, so it turns out most of my callbacks aren't interruptible by the closereqfcn. BUT, it turns out some are, and the reasons why seem very strange. If have a callback with:
`large computation -> imshow -> imshow
large computation -> set -> set -> set -> set
where the set command is setting the axes visible property to off, then no interruption seems to occur if I exit during the callback
Now, if I have:
large computation -> imshow -> set -> imshow -> set
matlab issues an error if I exit during the callback on the second set command. Also, if I have:
large computation -> imshow -> imshow -> set
matlab issues an error if I exit during the callback on the first set command.
large computation -> imshow -> imshow -> imshow
also issues an error on the third imshow if I cancel during the callback.
For some reason it seems that two successive calls to imshow makes my callback interruptible. Is it possible matlab implicitly calls drawnow or does something weird if you use multiple imshows? BTW, my matlab version is R2009a.
I never really trusted that Interruptible flag (or comparable mechanisms)...I immediately admit I have never used it a lot, but that was because when I was experimenting with it for the first time, I noticed that 'Interruptible', 'off' (and friends) seemed to have more exceptions to the rule than vindications of it -- headache material alert!
So, I got in the habit of tackling this sort of problem simply by using flags, and wrapping all callbacks that must really be uninterruptible in a locking/releasing function.
Something like this:
% Define a button
uicontrol(...
'style', 'pushbutton',...
'interruptible', 'off',... % Nice, but doesn't catch DeleteFcn, CreateFcn, ...
% CloseRequestFcn or ResizeFcn
% ...
% further definition of button
% ...
% Put callback in a wrapper:
'callback', #(src,evt) uninterruptibleCallback(#buttonCallback, src,evt)...
);
where uninterruptibleCallback() looks something like this:
function varargout = uninterruptibleCallback(callback, varargin)
% only execute callback when 'idle'
% (you can omit this if you don't want such strict ordering of callbacks)
while ~strcmp( get(mainFigure, 'userData'), 'idle' )
pause(0.01);
% ...or some other action you desire
end
% LOCK
set(mainFigure, 'userData', 'busy');
try
% call the "real" callback
[varargout{:}] = callback(varargin{:});
% UNLOCK
set(mainFigure, 'userData', 'idle');
catch ME
% UNLOCK
set(mainFigure, 'userData', 'idle');
throw(ME);
end
end
Which allows you to use this closeReqFcn() for your figure:
function closeReqFcn(~,~)
% only when the currently running locked callback (if any) has finished
while ~strcmp( get(mainFigure, 'userData'), 'idle' )
pause(0.01);
% ...or some other action you desire
end
% ...
% further clean-up tasks
% ...
% deletion
delete(mainFigure);
end
Theoretically, when you put all callbacks in this sort of schema, it is basically equal to managing your own event queue.
This of course has a few advantages, but many, many drawbacks -- you might want to think this through for a bit. This whole mechanism might be unacceptably slow for your use case, or you might need to define a few more locking functions with far more specific behavior.
In any case, I suspect it's a good place to start off from.
An alternative to #Rody Oldenhuis's solution is to start a timer inside the CloseRequestFcn to close the figure when no uninterruptible code is in progress (which could be indicated by a flag; Closing_Allowed).
function mainFig_CloseRequestFcn(hObject, eventdata, handles)
Time = 3; % Wait time before force killing (in sec)
Kill.tmr = timer('executionMode', 'fixedRate',...
'Period', 1/10,...
'TimerFcn', {#KillingTimer_Callback, handles});
Kill.counts = ceil(Time/Kill.tmr.Period);
setappdata(handles.mainFig,'Kill',Kill);
start(Kill.tmr);
function KillingTimer_Callback(hObject, eventdata, handles)
Kill = getappdata(handles.mainFig,'Kill');
Kill.counts = Kill.counts - 1; % Count down
setappdata(handles.mainFig,'Kill',Kill);
if Kill.counts == 0 || getappdata(handles.mainFig, 'Closing_Allowed')
stop(Kill.tmr);
delete(handles.mainFig);
end
if Kill.counts == 0 means time out, and closes the figure even if an uninterruptible task is in progress, which then would result in the same errors you get sometimes now, but if you know the maximum amount of time you need to finish the uninterruptible jobs, then you can set the Time above properly.
Finally wrap the uninterruptible code by setting the Closing_Allowed flag.
function pushbutton_Callback(hObject, eventdata, handles)
setappdata(handles.mainFig, 'Closing_Allowed', 0); % Closing is not allowed
pause(2);
setappdata(handles.mainFig, 'Closing_Allowed', 1); % Closing is allowed

Matlab GUI using GUIDE : Want to dynamically update graphs

I've written a Matlab script that reads in data using a virtual COMM port in real-time. I've done a significant amount of signal processing in an mfile.
Next, I felt the need to have a compact GUI that displays the information as summary.
I only recently started digging and reading more of Matlab's built-in GUI tool, GUIDE. I've followed a few tutorials and am successfully able to get my graphs to display on my GUI after a button-press.
However, I want the GUI to update in real-time. My data vector is constantly updating (reading in data from the COMM port). I want the GUI to keep updating the graphs with the newer data, as opposed to relying on a button press for an update. Can someone please point me in the right direction for background updating?
Here is the relevant code currently for the GUI:
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global data
global time
% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);
EDIT Changed code:
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%Setting it to display something when it ends
% t = timer('TimerFcn', 'timerOn=false; disp(''Updating GUI!'')',...
t = timer(...
'TasksToExecute', 10, ... % Number of times to run the timer object
'Period', 3, ...
'TimerFcn', GUIUpdate());
%Starting the timer
start(t)
function GUIUpdate()
global data
global time
%Parameters below axes
global min
global max
% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);
%Other parameters:
set(handles.mean, 'String', mean);
set(handles.max, 'String', max);
The error that I get is:
??? Error using ==> GUI_Learning>GUIUpdate
Too many output arguments.
Error in ==>
#(hObject,eventdata)GUI_Learning('pushbutton1_Callback',hObject,eventdata,guidata(hObject))
??? Error while evaluating uicontrol Callback
Here is an example using a timer with a timerFcn callback. I made a simple GUI with 1 axes and 1 button.
In the opening function I initialize the plot and create the timer. In the start button callback I start the timer and start manipulating the data. The timer function callback the just updates the y-data of the line via its handle. Below are the relevant functions from the GUI's M-file (snipped init section and output fcn.
function testTimer_OpeningFcn(hObject, eventdata, handles, varargin)
global y x
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
handles.plot = plot(handles.axes1,x,y);
handles.timer = timer('ExecutionMode','fixedRate',...
'Period', 0.5,...
'TimerFcn', {#GUIUpdate,handles});
handles.output = hObject;
guidata(hObject, handles);
% --- Executes on button press in startButton.
function startButton_Callback(hObject, eventdata, handles)
global y x
start(handles.timer)
for i =1:30
y = sin(x+i/10);
pause(1)
end
function GUIUpdate(obj,event,handles)
global y
set(handles.plot,'ydata',y);
You may want a Stop button to stop the timer depending on how your GUI is structured and were/how the data is updated.
Edit: Basic handles info some of this is pretty basic and you may already know it:
An individual handle to an object contains a bunch of properties that you can read with the get() function or set with the set() function. So for example maybe I wanted to change the text of the startButton for some reason in my GUI.
set(handles.startButton,'String','Something Other Than Start');
You may just want to set a break point in your code somewhere (maybe in a button press) and play around with the handles struct. Running get() commands on various objects to learn their properties.
Now the handles structure contains all of the ... umm... handles to your GUI's objects as well as any custom items that may be convenient for your to store there. Most GUI callbacks automatically get passed the handles struct so you have easy access to all parts of the GUI.
Ex. The 'startButton' callback was automatically passed handles. So I had easy access to the timer object via handles.timer.
Which brings me to sticking custom things into handles. In the opening function I added a new item to the handles structure handles.timer and handles.plot because I knew they would be useful in other callbacks (like button press and the timerFcn callback).
However, to store these things permanently you need to use the 'guidata' function. This function basically either stores the modified handles struct or retrieves a copy of handles depending on how you call it. So the following line in the opening function is storing the modified handles structure (added .timer and .plot) into the main GUI.
guidata(hObject,handles);
Basically any time you add something in handles you should have that line to make the change permanent.
Now the other method of calling it is:
handles = guidata(hObject); %hObject can be any handle who is a child of the main GUI.
This will retrieve the handles structure for the GUI.
And last handles.output = hObject is just the default output when you launch your GUI. IF you call your GUI via Matlab's command line like this h = myGUI; it should return the handle to your GUI.
You need to use a timer object. Set the callback to be the function that updates the plots.
Take a look at Making Graphs Responsive with Data Linking
and the linkdata command.
If the same variable appears in plots in multiple figures, you can
link any of the plots to the variable. You can use linked plots in
concert with Marking Up Graphs with Data Brushing, but also on their
own. Linking plots lets you
Make graphs respond to changes in variables in the base workspace or within a function
Make graphs respond when you change variables in the Variable Editor and Command Line
Modify variables through data brushing that affect different graphical representations of them at once
Create graphical "watch windows" for debugging purposes
Watch windows are useful if you program in the MATLAB language. For
example, when refining a data processing algorithm to step through
your code, you can see graphs respond to changes in variables as a
function executes statements.
I made a quick and dirty test seen below and I am not sure how this will work in a GUI verses a function but may do the trick.
Note 1: I had to add a break point in my subroutine where it modifies the global y to actually see the plot auto-update. You may need some combination of drawnow, pause, or a timer if data is getting changed rapidly.
function testLinking()
global x y
%Links failed if the global did not also exist in the base workspace
evalin('base','global x y');
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
h = plot(x,y,'ydatasource','y','xdatasource','x');
linkdata on
testSub
function testSub()
%Test to see if a sub can make a linked global refresh
global x y
for i = 1:10
%This should automatically update the plot.
y = sin(x+i/10);
end
Edit: there may be ways around the use of globals depending on how your functions are structured ... but I don't have time to dig into it to much.
You can add a callback on the serial object that executes a plotting function. You must attach the callback to the 'BytesAvailableFcn' event on the object (see this for more details on the properties of the com object).
Essentially, when there are bytes available on the com port, you instruct matlab to run a specific function. In your case, it will be the function updating the GUI. If you need to process the incoming data first, then your callback function will first do the signal processing and then do the plotting commands.