matlab: send function's values to other function - matlab

I have two GUI-s.
the first GUI is named: GUI1, there the user inserts three values.
then the user has a button 'Submit', so I want these values to be sent to other function (GUI2) every time he presses it.
my function GUI2.m gets three elements:
function GUI2(x,y,r)
.
.
.
end
and this is the first GUI:
function [E] = GUI1()
num_of_columns = 3;
E = []; % In case the user closes the GUI.
S.fh = figure('units','pixels',...
'position',[500 500 850 100],...
'menubar','none',...
'name','Number Of Columns',...
'numbertitle','off',...
'resize','off');
num = 0;
for i = 1:num_of_columns
S.ed(i) = uicontrol('style','edit',...
'units','pix',...
'position',[num 60 100 30],...
'string','');
num = num + 500/num_of_columns;
uicontrol(S.ed(1)) % Make the editbox active.
end
S.pb = uicontrol('style','pushbutton',...
'units','pix',...
'position',[290 20 180 30],...
'string','Submit',...
'callback',{#pb_call});
uiwait(S.fh) % Prevent all other processes from starting until closed.
function [] = pb_call(varargin)
% Callback for the pushbutton.
E = get(S.ed(:),'string');
E{1} = str2num(E{1});
E{2} = str2num(E{2});
E{3} = str2num(E{3});
In this line I want to send E{1}, E{2} and E{3} to GUI2
end
end

how about:
GUI2(E{1},E{2},E{3})

Related

Matlab GUI: How to update handles structure?

I am working on GUI. I want to store data in extra fields created in handles structure. However, I don't know how to update handles structure properly when callback function ends. Please, give any advice.
My simplified program
Set number of signal (1-10). Each signal has 3 parameters.
Read parameter for selected signal from array created in handles structure
(default are zeros).
Edit parameter, update the array.
GUI
function simple_gui(hObject, h)
h.fig = figure(...
'Units','pix',...
'Position',[50 50 500 400],...
'Visible','default',...
'Name','GUI',...
'NumberTitle','off',...
'Resize','on');
table = {'1' , '2', '3' , '4', '5', '6', '7', '8', '9', '10' };
h.number = uicontrol(...
'Units','characters',...
'Max',10,...
'Min',1,...
'String',table,...
'Style','popupmenu',...
'Value',1,...
'Position',[37.4 28.3846153846154 19.4 1.61538461538462],...
'BackgroundColor',[1 1 1]);
h.edit1 = uicontrol(...
'Units','pix',...
'String','0',...
'Style','edit',...
'Position',[180 280 50 20],...
'BackgroundColor',[1 1 1],...
'FontSize',10);
h.edit2 = uicontrol(...
'Units','pix',...
'String','0',...
'Style','edit',...
'Position',[180 255 50 20],...
'Children',[],...
'FontSize',10);
h.edit3 = uicontrol(...
'Units','pix',...
'String','0',...
'Style','edit',...
'Position',[180 230 50 20],...
'FontSize',10);
Main code:
h.parameter1 = zeros(1,10);
h.parameter2 = zeros(1,10);
h.parameter3 = zeros(1,10);
h.signal_no = 0;
h.number.Callback = {#number_Callback, h};
h.edit1.Callback = {#parameter_change_Callback, h};
h.edit2.Callback = {#parameter_change_Callback, h};
h.edit3.Callback = {#parameter_change_Callback, h};
guidata(h.fig, h);
function number_Callback(hObject,eventdata, h)
h = guidata(hObject);
h.signal_no = hObject.Value;
k = h.signal_no;
h.edit1.String = h.parameter1(k);
h.edit2.String = h.parameter2(k);
h.edit3.String = h.parameter3(k);
guidata(hObject,h);
function parameter_change_Callback(hObject,eventdata, h)
h = guidata(hObject);
k = h.signal_no;
h.parameter1(k) = str2double(h.edit1.String);
h.parameter2(k) = str2double(h.edit2.String);
h.parameter3(k) = str2double(h.edit3.String);
guidata(hObject, h);
In summary:
Call guidata(handleObject, varToStore) (documentation) at the end of GUI callback functions to ensure updates to one modified variable are stored. Here, handleObject is either your figure's handle or a child of it, and varToStore is the updated variable you want stored; it is often a structure.
The syntax for retrieving stored data from a figure or child handle:
handles = guidata(gcbo); % gcbo will get the callback object (instance of handle class).
handles.propToUpdate = handles.propToUpdate+1;
guidata(gcbo,handles); % stores the updated struct
In addition:
You won't see the changes from your popupmenu reflected in your edit boxes in the GUI with the current code because you are assigning the numeric values to a edit handle's String field. You call str2double() when taking values this field, and just need to do the reverse (num2str()) to get the displayable values back in. Here's the updated code with a simplified callback declaration
h.number.Callback = #number_Callback;
function number_Callback(hObject,~)
h = guidata(hObject);
h.signal_no = hObject.Value;
k = h.signal_no;
h.edit1.String = num2str(h.parameter1(k));
h.edit2.String = num2str(h.parameter2(k));
h.edit3.String = num2str(h.parameter3(k));
guidata(hObject,h);
end

How to plot the CPU usage of Matlab

i have a code that displays the CPU usage of Matlab, my problem is how to PLOT the CPU usage over time because the this code does NOT save any variables in the workspace,I need a method for storing the CPU usage in an array when the code is run so that i can plot it
Thanks for your time.
here is the code:
function hcol = CPU_monitor
h = create_gui;
end
function mon = createMonitor
MatlabProcess = System.Diagnostics.Process.GetCurrentProcess(); %// "Matlab" process
cpuIdleProcess = 'Idle';
mon.NumOfCPU = double(System.Environment.ProcessorCount);
mon.ProcPerfCounter.Matlab = System.Diagnostics.PerformanceCounter('Process', '% Processor Time', MatlabProcess.ProcessName);
mon.ProcPerfCounter.cpuIdle = System.Diagnostics.PerformanceCounter('Process', '% Processor Time', cpuIdleProcess);
end
function updateMeasure(obj,evt,hfig)
h = guidata(hfig);
%// Calculate the cpu usage
cpu.total = 100 - h.mon.ProcPerfCounter.cpuIdle.NextValue / h.mon.NumOfCPU;
cpu.matlab = h.mon.ProcPerfCounter.Matlab.NextValue / h.mon.NumOfCPU;
%// update the display
set(h.txtTotalCPU,'String',num2str(cpu.total,'%5.2f %%'))
set(h.txtMatlabCPU,'String',num2str(cpu.matlab,'%5.2f %%'))
end
function StartMonitor(obj,evt)
h = guidata(obj);
start(h.t)
end
function StopMonitor(obj,evt)
h = guidata(obj);
stop(h.t)
end
function h = create_gui %// The boring part
h.fig = figure('Unit','Pixels','Position',[200 800 240 120],'MenuBar','none','Name','CPU usage %','NumberTitle','off');
h.btnStart = uicontrol('Callback',#StartMonitor,'Position',[10 80 100 30],'String', 'START');
h.btnStart = uicontrol('Callback',#StopMonitor,'Position',[130 80 100 30 ],'String', 'STOP');
h.lbl1 = uicontrol('HorizontalAlignment','right','Position',[10 50 100 20],'String','TOTAL :','Style','text');
h.txtTotalCPU = uicontrol('Position',[130 50 100 20],'String','0','Style','text');
h.lbl2 = uicontrol('HorizontalAlignment','right','Position',[10 10 100 20],'String','Matlab :','Style','text');
h.txtMatlabCPU = uicontrol('Position',[130 10 100 20],'String','0','Style','text');
movegui(h.fig,'center')
%// create the monitor
h.mon = createMonitor;
%// Create the timer
h.t = timer;
h.t.Period = 0.25;
h.t.ExecutionMode = 'fixedRate';
h.t.TimerFcn = {#updateMeasure,h.fig};
h.t.TasksToExecute = Inf;
%// store the handle collection
guidata(h.fig,h)
end
one way is to save the variables to a file and read and plot it after you stop. So you add a dlmwrite command in the updateMeasure function, a tic to start the timer in StartMonitor, and dlmread and plot in StopMonitor. Of course this is quick and dirty as the file created will be needed to be deleted or checked so you wont continue to append to it in the later uses.
This is everything
function hcol = CPU_monitor
h = create_gui;
end
function mon = createMonitor
MatlabProcess = System.Diagnostics.Process.GetCurrentProcess(); %// "Matlab" process
cpuIdleProcess = 'Idle';
mon.NumOfCPU = double(System.Environment.ProcessorCount);
mon.ProcPerfCounter.Matlab = System.Diagnostics.PerformanceCounter('Process', '% Processor Time', MatlabProcess.ProcessName);
mon.ProcPerfCounter.cpuIdle = System.Diagnostics.PerformanceCounter('Process', '% Processor Time', cpuIdleProcess);
end
function updateMeasure(obj,evt,hfig)
h = guidata(hfig);
%// Calculate the cpu usage
cpu.total = 100 - h.mon.ProcPerfCounter.cpuIdle.NextValue / h.mon.NumOfCPU;
cpu.matlab = h.mon.ProcPerfCounter.Matlab.NextValue / h.mon.NumOfCPU;
dlmwrite('cpulog.txt', [toc, cpu.total , cpu.matlab], '-append');
%// update the display
set(h.txtTotalCPU,'String',num2str(cpu.total,'%5.2f %%'))
set(h.txtMatlabCPU,'String',num2str(cpu.matlab,'%5.2f %%'))
end
function StartMonitor(obj,evt)
h = guidata(obj);
start(h.t)
tic
end
function StopMonitor(obj,evt)
h = guidata(obj);
stop(h.t)
data=dlmread('cpulog.txt');
data(1,:)=[];
figure;plot(data(:,1),data(:,2),data(:,1) ,data(:,3));
legend('total cpu','matlab cpu'); xlabel('sec'); ylabel('%');
end
function h = create_gui %// The boring part
h.fig = figure('Unit','Pixels','Position',[200 800 240 120],'MenuBar','none','Name','CPU usage %','NumberTitle','off');
h.btnStart = uicontrol('Callback',#StartMonitor,'Position',[10 80 100 30],'String', 'START');
h.btnStart = uicontrol('Callback',#StopMonitor,'Position',[130 80 100 30 ],'String', 'STOP');
h.lbl1 = uicontrol('HorizontalAlignment','right','Position',[10 50 100 20],'String','TOTAL :','Style','text');
h.txtTotalCPU = uicontrol('Position',[130 50 100 20],'String','0','Style','text');
h.lbl2 = uicontrol('HorizontalAlignment','right','Position',[10 10 100 20],'String','Matlab :','Style','text');
h.txtMatlabCPU = uicontrol('Position',[130 10 100 20],'String','0','Style','text');
movegui(h.fig,'center')
%// create the monitor
h.mon = createMonitor;
%// Create the timer
h.t = timer;
h.t.Period = 0.25;
h.t.ExecutionMode = 'fixedRate';
h.t.TimerFcn = {#updateMeasure,h.fig};
h.t.TasksToExecute = Inf;
%// store the handle collection
guidata(h.fig,h)
end

Matlab - Initialize a script in every two seconds

I tried to write an animation code in Matlab that repeats itself in every two seconds. The core animation scheme is as below:
Please take care the gif is repeating the core animation, originally there is only one cycle.
Here is the code:
% Figure settings
h= figure(2);
set(h, 'Position', [100 50 1200 750])
set(h,'Toolbar','None','Menubar','None')
set(h,'Name','Animation')
set(gcf,'doublebuffer','off');
set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual',...
'climmode','manual','alimmode','manual');
xlim([-200 1350])
ylim([-250 800])
set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);
%Parameters
diameter = 60; %spot çapı
RamanX = 350; %ölçüm noktssı x konumu
nOfSpots = 4; %spot sayısı
spotCount = 0; %toplam spot sayısı
initPos = [50 150;50 300; 50 450; 50 600]; %konum 1
posII = [350 150;350 300; 350 450; 350 600]; %konum 2
Choice = rand(1,4)<.5; %Ölçüm sonunda verilen karar
deltaY2 = 100; % spotlar arası mesafe
x11 = zeros(nOfSpots,2);
x22 = zeros(nOfSpots,2);
x22a = zeros(nOfSpots,2);
x22b = zeros(nOfSpots,2);
for i=1:nOfSpots
x11(i,:) = [RamanX 150*(i-1)];
x22(i,:) = [800 50+deltaY2*(i-1)];
end
for i=1:nOfSpots/2
x22a(2*i-1,:) = [1280 -270+250*(i-1)];
x22a(2*i,:) = [1075 -270+250*(i-1)];
x22b(2*i-1,:) = [1280 220+250*(i-1)];
x22b(2*i,:) = [1075 220+250*(i-1)];
end
%Add 4 Circles to initial position
for i=1:nOfSpots
% Drag & Drop elipsler yerleştiriliyor
spot(i) = imellipse(gca, [initPos(i,1),initPos(i,2),diameter,diameter]);
spotCount = spotCount+1;
%elips özellikleri
setFixedAspectRatioMode(spot(spotCount), 'TRUE');
setResizable(spot(spotCount),0);
posSpot(spotCount,:) = getPosition(spot(i));
end
%Move Circles to posII
r = sqrt(sum(bsxfun(#minus,posII(:,1),initPos(:,1)).^2,2));
v = 30;
stepsize = ceil(r/v);
xstep = (posII(:,1)-initPos(:,1))/stepsize;
for i=1:stepsize
for j=1:nOfSpots
setPosition(spot(j), [initPos(j,1)+xstep(j)*i, initPos(j,2), diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
pause(0.15)
end
%Move Circles to posIII
velocity = 30;
r2a = sqrt(sum(bsxfun(#minus,x22a,x11).^2,2));
stepsize2a = max(ceil(r2a/velocity));
r2b = sqrt(sum(bsxfun(#minus,x22a,x11).^2,2));
stepsize2b = max(ceil(r2b/velocity));
% Eğer öllçüm seçimi 1 ise taşı
for i=1:nOfSpots
if(Choice(i))
xstep2(i) = (x22a(i,1)-x11(i,1))./stepsize2a;
ystep2(i) = (x22a(i,2)-x11(i,2))./stepsize2a;
else
xstep2(i) = (x22b(i,1)-x11(i,1))./stepsize2b;
ystep2(i) = (x22b(i,2)-x11(i,2))./stepsize2b;
end
end
stepsize2 = max([stepsize2a stepsize2b]);
% Eğer ölçüm seçimi 0 ise taşı
for i=1:stepsize2
for j=1:nOfSpots
if(Choice(j))
setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
end
pause(0.15)
end
for i=1:stepsize2
for j=1:nOfSpots
if(~Choice(j))
setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
end
pause(0.15)
end
if(spotCount > 0)
for i=1:4
delete(spot(i))
end
end
The code doing this is a script not a function, say "animation.m". Now I am trying repeat this code in every 2 seconds. I tried to use loops with tic - toc commands, but the loop does not go to other cycle before finishing "animation.m". I need to get it work in the background.
One of my friend suggested me to use trigger. But, honestly, I could not apply the trigger command for my code even when I functionalized it.
Any help?
Edit:
The graphical flow chart of the problem is below:
I created an example that shows how it could be done.
Modifying your code, to draw just "one animated step" was too much work.
I decided to used your code to create all frames from advance (for example purpose).
I guess you are going to realize, that implementing background animation in Matlab is more difficult than you thought (unless I missed some hidden Matlab feature).
Matlab has very limited threading support, so I used a periodic timer.
My code sample does the following:
Build animation - create a cell array of all animated images.
You should avoid it, because it takes to much time (and memory).
I used it instead of modifying your code to draw one animated image.
Setup a periodic timer object with 0.2 seconds period (0.2 as an example).
I added a loop that illustrates the foreground processing (calculating sin(x) as an example).
Notice: I added small pause in the "foreground processing" loop.
The timer invokes a callback function every 0.2 seconds.
In the callback function the next animated frame is shown.
The timer is used for simulating a background execution.
You should replace the imshow, with your "animation step" function, that draws the frame (instead of showing a frame created from advance).
Here is the code sample (with your modified code included):
function TimerAnimation()
%Build set of images for animation.
[h_figure, Frames] = BuildAnimation();
t = timer;
t.TimerFcn = #timerFcn_Callback; %Set timer callback function
t.ExecutionMode = 'fixedRate'; %Set mode to "singleShot" - execute TimerFcn only once.
t.StartDelay = 0.1; %Wait 0.1 second from start(t) to executing timerFcn_Callback.
t.Period = 0.2; %Set period to 0.2 seconds.
%Turn on figure visibility
set(h_figure, 'Visible', 'on');
frame_counter = 1;
start(t) %Start timer;
%Do some other job...
%The animation is executed in the background (kind of in the background).
for x = 1:20000
y = sin(x/10000); %Calculate somthing...
if (mod(x, 100) == 0)
disp(['sin(', num2str(x/10000), ') = ', num2str(y)]); %Display somthing...
end
if (~isvalid(h_figure))
%Break loop if user closed the animation figure.
break;
end
%Must insert pause to "tight loop", allowing animation to run.
pause(0.01);
end
stop(t) %Stop timer;
delete(t); %Delete timer object.
if (~isvalid(h_figure))
close(h_figure);
end
%Timer function is executed every period of 0.2 seconds.
function timerFcn_Callback(mTimer, ~)
%Increse animation frame counter.
%figure(h_figure); %Set fo h_figure to be active figure.
h_axes = get(h_figure, 'CurrentAxes'); %Get axes of h_figure
imshow(Frames{frame_counter}, 'Parent', h_axes); %Display frame number frame_counter.
drawnow; %Force refresh.
frame_counter = mod(frame_counter, length(Frames)) + 1; %Advance to next frame (cyclically).
end
end
function [h, Frames] = BuildAnimation()
%Build set of images for animation.
%h - return handle to figure
%Frames - return cell array of animation images.
counter = 1;
% Figure settings
%h = figure(2);
%Create invisible figure.
h = figure('Visible', 'off');
set(h, 'Position', [100 50 1200 750])
set(h,'Toolbar','None','Menubar','None')
set(h,'Name','Animation')
set(gcf,'doublebuffer','off');
set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual',...
'climmode','manual','alimmode','manual');
xlim([-200 1350])
ylim([-250 800])
set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);
%Parameters
diameter = 60; %spot ?ap?
RamanX = 350; %?l??m noktss? x konumu
nOfSpots = 4; %spot say?s?
spotCount = 0; %toplam spot say?s?
initPos = [50 150;50 300; 50 450; 50 600]; %konum 1
posII = [350 150;350 300; 350 450; 350 600]; %konum 2
Choice = rand(1,4)<.5; %?l??m sonunda verilen karar
deltaY2 = 100; % spotlar aras? mesafe
x11 = zeros(nOfSpots,2);
x22 = zeros(nOfSpots,2);
x22a = zeros(nOfSpots,2);
x22b = zeros(nOfSpots,2);
for i=1:nOfSpots
x11(i,:) = [RamanX 150*(i-1)];
x22(i,:) = [800 50+deltaY2*(i-1)];
end
for i=1:nOfSpots/2
x22a(2*i-1,:) = [1280 -270+250*(i-1)];
x22a(2*i,:) = [1075 -270+250*(i-1)];
x22b(2*i-1,:) = [1280 220+250*(i-1)];
x22b(2*i,:) = [1075 220+250*(i-1)];
end
%Add 4 Circles to initial position
for i=1:nOfSpots
% Drag & Drop elipsler yerle?tiriliyor
spot(i) = imellipse(gca, [initPos(i,1),initPos(i,2),diameter,diameter]);
spotCount = spotCount+1;
%elips ?zellikleri
setFixedAspectRatioMode(spot(spotCount), 'TRUE');
setResizable(spot(spotCount),0);
posSpot(spotCount,:) = getPosition(spot(i));
end
%Move Circles to posII
r = sqrt(sum(bsxfun(#minus,posII(:,1),initPos(:,1)).^2,2));
v = 30;
stepsize = ceil(r/v);
xstep = (posII(:,1)-initPos(:,1))/stepsize;
for i=1:stepsize
for j=1:nOfSpots
setPosition(spot(j), [initPos(j,1)+xstep(j)*i, initPos(j,2), diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
%pause(0.15)
%Get frame, convert frame to image, and store image in Frames
Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end
%Move Circles to posIII
velocity = 30;
r2a = sqrt(sum(bsxfun(#minus,x22a,x11).^2,2));
stepsize2a = max(ceil(r2a/velocity));
r2b = sqrt(sum(bsxfun(#minus,x22a,x11).^2,2));
stepsize2b = max(ceil(r2b/velocity));
% E?er ?ll??m se?imi 1 ise ta??
for i=1:nOfSpots
if(Choice(i))
xstep2(i) = (x22a(i,1)-x11(i,1))./stepsize2a;
ystep2(i) = (x22a(i,2)-x11(i,2))./stepsize2a;
else
xstep2(i) = (x22b(i,1)-x11(i,1))./stepsize2b;
ystep2(i) = (x22b(i,2)-x11(i,2))./stepsize2b;
end
end
stepsize2 = max([stepsize2a stepsize2b]);
% E?er ?l??m se?imi 0 ise ta??
for i=1:stepsize2
for j=1:nOfSpots
if(Choice(j))
setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
end
% pause(0.15)
%Get frame, convert frame to image, and store image in Frames
Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end
for i=1:stepsize2
for j=1:nOfSpots
if(~Choice(j))
setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
end
% pause(0.15)
%Get frame, convert frame to image, and store image in Frames
Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end
if(spotCount > 0)
for i=1:4
delete(spot(i))
end
end
imshow(Frames{1})
end
Example for what I meant by "drawing just one animated step":
function TimerAnimation2()
%Initiazlie animation.
param = InitAnimation();
%Same code as in previous example.
t = timer;t.TimerFcn = #timerFcn_Callback;t.ExecutionMode = 'fixedRate';t.StartDelay = 0.1;t.Period = 0.2;start(t)
for x = 1:20000;if (~isvalid(param.h)), break;end;pause(0.01);end
stop(t);delete(t);if (isvalid(param.h)), close(param.h);end
%Timer function is executed every period of 0.2 seconds.
function timerFcn_Callback(mTimer, ~)
%Animation single step
param = StepAnimation(param);
end
end
function param = InitAnimation()
h = figure;
set(h, 'Position', [100 50 1200 750]);set(h,'Toolbar','None','Menubar','None');set(h,'Name','Animation');set(gcf,'doublebuffer','off');
set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual', 'climmode','manual','alimmode','manual');
xlim([-200 1350]);ylim([-250 800]);set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);
%Initialize param struct (param struct keeps animation parameters).
param.h = h;
param.x = 10;
param.y = 10;
%Draw rectangle in position x, y
h_axes = get(param.h, 'CurrentAxes');
rectangle('Position', [param.x param.y 20 20], 'Parent', h_axes);
end
%Example fo single animation step
%Get exsiting animation param as input, and retuen updated param as output.
function param = StepAnimation(param)
h_axes = get(param.h, 'CurrentAxes');
%Update param (to be used in next StepAnimation).
param.x = param.x + 10;
param.y = param.y + 10;
if (param.x > 500), param.x = 10;end
if (param.y > 500), param.y = 10;end
%Draw rectangle in position x, y
rectangle('Position', [param.x param.y 20 20], 'Parent', h_axes)
drawnow; %Force refresh.
end

matlab: close the gui if the user presses the close button

I made a GUI that gets 2 elements: files (list of files) and options (I will explain later).
there is a function that calls the function below:
// asume that this is my 'options'
options{1} = {'Treatment', 't1', 't2'};
options{2} = {'Tree', '1', '2'};
options{3} = {'Replica', 'r1', 'r2', 'r3'};
// asume that this is my 'files' (may be more than 2 images
files{1} = 'C:\Documents and Settings\erezalon\Desktop\gib_proj_02.10.12\fina3_32bit\IMG_4640.JPG';
files{2} = 'C:\Documents and Settings\erezalon\Desktop\gib_proj_02.10.12\fina3_32bit\grapes03.jpg';
mydata = mainGUI(options, files).
// here I want to check 'mydata'. if it is equal to zero or not.
for each image, the GUI is created in the function 'mainGUI' (but each time, one GUI is showed till the user presses 'next').
I want to do the next thing:
if the user presses the close button in the GUI, I want to stop the displaying of the other GUI-s and set 'data = 0'. then, I will check what is the returned element ('mydata') and if it's equal to 0, I will know that the user closed the GUI and I will act as needed.
I tried to do this by the 'cmdClose_Callback' but it doesn't work.
assume that 'files' = two images, so this is the GUI of the first image.
I press the close button:
and got the GUI of the second image despite of closing the GUI of the first image.
I want that when I close the GUI, the other GUI-s don't appear.
this is my code:
function data = mainGUI(options, files)
%# current options
j = 1;
ops = cellfun(#(c) c(1), options, 'Uniform',false);
data{j} = [ops{1:length(ops)}];
j = j + 1;
options = cellfun(#(c) c(2:1:end), options, 'Uniform',false);
clear ops;
ops = cellfun(#(c) c(1), options, 'Uniform',false);
opts = [ops{1:length(ops)}];
%# create main figure, with plot and options button
hFig = figure('Name','window 1','Visible','Off');
a = 1
callback
%# options button callback function
function callback(o,e)
a = 2
%# save current options (sharing data between the two GUIs)
setappdata(hFig, 'opts',opts);
%# display options dialog and wait for it
for k=1: length(files)
hOptsGUI = secondaryGUI(hFig, options, k, length(files));
img = imread(files{k}); %# Read the data from image file data
hAxes = axes('Parent',hOptsGUI,'Units','pixels','Position',[362 242 424 359]); %# so the position is easy to define
image(img,'Parent',hAxes); %# Plot the image
set(hAxes,'Visible','off'); %# Turn the axes visibility off
a = 3
waitfor(hOptsGUI);
a = 4
%# get new options, and update plot accordingly
opts = getappdata(hFig, 'opts');
data{j} = opts;
j = j + 1;
end
end
end
function hFig = secondaryGUI(hParentFig, options, k, num_files)
%# create figure
a = 5
hFig = figure('Name','Step 3 of 4: Choose data for each image','Menubar','none', 'Resize','off', ...
'WindowStyle','modal', 'Position',[300 300 1150 600], 'CloseRequestFcn',#cmdClose_Callback);
set(gcf,'NumberTitle','off')
movegui(hFig, 'center');
options = cellfun(#(c) c(end:-1:1), options, 'Uniform',false);
num = length(options);
%# get saved settings
selected = getappdata(hParentFig, 'opts');
a = 6
%# top/bottom panels
hPanBot = uipanel('Parent',hFig, 'BorderType','none', ...
'Units','normalized', 'Position',[0 0.0 1 0.2]);
hPanTop = uipanel('Parent',hFig, 'BorderType','none', ...
'Units','normalized', 'Position',[0 0.2 1 0.2]);
%# buttongroups in top panel
hBtnGrp = zeros(1,num);
width = 1/num;
for i=1:num
%# create button group
hBtnGrp(i) = uibuttongroup('Parent',hPanTop, ...
'Units','normalized', 'Position',[(i-1)*width 0 width 1]);
%# populate it with radio buttons
height = 1./numel(options{i});
for j=1:numel(options{i})
h = uicontrol('Parent',hBtnGrp(i), 'Style','Radio', ...
'Units','normalized', 'Position',[0.05 (j-1)*height 0.9 height], ...
'String',options{i}{j});
%# set initially selected values
if strcmp(selected{i},options{i}{j})
set(hBtnGrp(i), 'SelectedObject',h)
end
end
end
if k ~= num_files
%# save button in bottom panel
uicontrol('Parent',hPanBot, 'Style','pushbutton', ...
'Units','normalized', 'Position',[0.3 0.2 0.4 0.2], ...
'String','next', 'Callback',#callback);
else
uicontrol('Parent',hPanBot, 'Style','pushbutton', ...
'Units','normalized', 'Position',[0.3 0.2 0.4 0.2], ...
'String','start', 'Callback',#callback);
end
%# save button callback function
function callback(o,e)
a = 7
%# get selected values
hObjs = get(hBtnGrp(:), 'SelectedObject');
vals = get(cell2mat(hObjs),{'String'});
%# update settings
setappdata(hParentFig, 'opts',vals);
close(hFig)
a = 8
end
function cmdClose_Callback(hObject,varargin)
disp(['Close Request coming from: ',get(hObject,'Type')]);
a = 9
%do cleanup here
delete(hFig);
a = 10
end
end
if 'files' has two images, I push the 'next' button for the first figure, and in the second figure I close, I get:
a = 1
a = 2
a = 5
a = 6
a = 3
a = 7
Close Request coming from: figure
a = 9
a = 10
a = 8
a = 4
a = 5
a = 6
a = 3
Close Request coming from: figure
a = 9
a = 10
a = 4
above the line: hOptsGUI = secondaryGUI(hFig, options, k, length(files));
I tried to put some lines. In order to testthe lines, I print a fit message:
if (ishandle(hFig))
disp('exists');
else disp('was closed');
end;
but it doesn't work :/
for each GUI that the user will close, the next callback will called:
function callback(o,e)
%# get selected values
hObjs = get(hBtnGrp(:), 'SelectedObject');
vals = get(cell2mat(hObjs),{'String'});
%# update settings
setappdata(hParentFig, 'opts',vals);
%# close options dialog
close(hFig)
end
so I just need to know in the next 'for loop' if this callback was called:
for k=1: length(files)
how can I do that?
Just check to see if hFig1 is a valid handle before you create the second figure.
if ishandle(hFig1)
hFig2 = figure(...)
else
return; % do something else
end
Repeat as needed.
function data = mainGUI(options, files)
% ...
% create main figure, with plot and options button
hFig = figure('Name','window 1','Visible','Off');
complete = callback;
if complete == 1
data = data;
else
data = 0;
end
% options button callback function
function complete = callback(o,e)
%save current options (sharing data between the two GUIs)
setappdata(hFig, 'opts',opts);
% display options dialog and wait for it
complete = 0;
for k = 1 : length(files)
hOptsGUI = secondaryGUI(hFig, options, k, length(files));
% ...
end
% we reached the end of the loop!
complete = 1;
end
I succeeded!
I used setappdata and getappdata in order to know if the second callback was called.
#Derek, Derek, thank you very much for your help and that you spent a lot of time for me!
function data = mainGUI(options, files)
%# current options
j = 1;
ops = cellfun(#(c) c(1), options, 'Uniform',false);
data{j} = [ops{1:length(ops)}];
j = j + 1;
options = cellfun(#(c) c(2:1:end), options, 'Uniform',false);
clear ops;
ops = cellfun(#(c) c(1), options, 'Uniform',false);
opts = [ops{1:length(ops)}];
%# create main figure, with plot and options button
hFig = figure('Name','window 1','Visible','Off');
callback
%# options button callback function
function callback(o,e)
%# save current options (sharing data between the two GUIs)
setappdata(hFig, 'opts',opts);
%# display options dialog and wait for it
for k=1: length(files)
hOptsGUI = secondaryGUI(hFig, options, k, length(files));
img = imread(files{k}); %# Read the data from your image file
hAxes = axes('Parent',hOptsGUI,'Units','pixels','Position',[362 242 424 359]); %# so the position is easy to define
image(img,'Parent',hAxes); %# Plot the image
set(hAxes,'Visible','off'); %# Turn the axes visibility off
out = 'FALSE';
setappdata(hFig,'some_var',out);
% show the images
%%Im = imread(files{k});
%%AxesH = axes('Units', 'pixels', 'position', [0.5, 10, 400, 260], 'Visible', 'off');
%%image('Parent', AxesH, 'CData', Im); %# add other property-value pairs as needed
waitfor(hOptsGUI);
some_other_var = getappdata(hFig,'some_var');
if (strcmp(some_other_var, 'OK') == 1)
%# get new options, and update plot accordingly
opts = getappdata(hFig, 'opts');
data{j} = opts;
j = j + 1;
else
k = length(files);
data = 0;
return;
end;
end
end
end
function hFig = secondaryGUI(hParentFig, options, k, num_files)
%# create figure
hFig = figure('Name','Step 3 of 4: Choose data for each image','Menubar','none', 'Resize','off', ...
'WindowStyle','modal', 'Position',[300 300 1150 600]);
set(gcf,'NumberTitle','off')
movegui(hFig, 'center');
options = cellfun(#(c) c(end:-1:1), options, 'Uniform',false);
num = length(options);
%# get saved settings
selected = getappdata(hParentFig, 'opts');
%# top/bottom panels
hPanBot = uipanel('Parent',hFig, 'BorderType','none', ...
'Units','normalized', 'Position',[0 0.0 1 0.2]);
hPanTop = uipanel('Parent',hFig, 'BorderType','none', ...
'Units','normalized', 'Position',[0 0.2 1 0.2]);
%# buttongroups in top panel
hBtnGrp = zeros(1,num);
width = 1/num;
for i=1:num
%# create button group
hBtnGrp(i) = uibuttongroup('Parent',hPanTop, ...
'Units','normalized', 'Position',[(i-1)*width 0 width 1]);
%# populate it with radio buttons
height = 1./numel(options{i});
for j=1:numel(options{i})
h = uicontrol('Parent',hBtnGrp(i), 'Style','Radio', ...
'Units','normalized', 'Position',[0.05 (j-1)*height 0.9 height], ...
'String',options{i}{j});
%# set initially selected values
if strcmp(selected{i},options{i}{j})
set(hBtnGrp(i), 'SelectedObject',h)
end
end
end
if k ~= num_files
%# save button in bottom panel
uicontrol('Parent',hPanBot, 'Style','pushbutton', ...
'Units','normalized', 'Position',[0.3 0.2 0.4 0.2], ...
'String','next', 'Callback',#callback);
else
uicontrol('Parent',hPanBot, 'Style','pushbutton', ...
'Units','normalized', 'Position',[0.3 0.2 0.4 0.2], ...
'String','start', 'Callback',#callback);
end
%# save button callback function
function callback(o,e)
out = 'OK';
setappdata(hParentFig,'some_var',out);
%# get selected values
hObjs = get(hBtnGrp(:), 'SelectedObject');
vals = get(cell2mat(hObjs),{'String'});
%# update settings
setappdata(hParentFig, 'opts',vals);
%# close options dialog
close(hFig)
end
function cmdClose_Callback(hObject,varargin)
%do cleanup here
delete(hFig);
end
end
There is no call to close the figure from the first GUI.
You may want to add a call close(hFig) to the end of the mainGUI function.

Matlab makes the loops run simultaneously

Unfortunately, I have two loops. that's why my code makes the first loop run and only when it is finished, it makes the second loop run.
But I want the gui to show the data simultaneously: in the hAxes and in the loading1.
How can I make it?
hFigure = figure('units','pixels','position',[300 300 424 470],'menubar','none',...
'name','start processing','numbertitle','off','resize','off');
hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]);
loading1 = uicontrol('style','text','unit','pix','position',[0 72 424 40],...
'backgroundcolor','r','fontsize',20);
%% shows the data on hAxes
for i = 5:100
if mod(i,2) == 0
set(hAxes,'Color','b');
else
set(hAxes,'Color','g');
end
drawnow;
end
%% shows the data on loading1
for i=1:200
image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
set(loading1,'string',image2);
drawnow;
end
this code is of Peter:
function test1
hFigure = figure('units','pixels','position',[300 300 424 470],'menubar','none','name','start processing','numbertitle','off','resize','off');
% Your other setup calls
hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]);
loading1 = uicontrol('style','text','unit','pix','position',[0 72 424 40],'backgroundcolor','r','fontsize',20);
c = 1;
t = timer('TimerFcn', #color_change_fcn,'StartDelay',1.0);
start(t);
for i=1:200
image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
set(loading1,'string',image2);
drawnow;
end
function color_change_fcn
if mod(c,2) == 0
set(hAxes,'Color','b');
else
set(hAxes,'Color','g');
end
drawnow;
c = c + 1;
end
end
It doesn't work (doesn't show the hAxes). I saw it doesn't make the color_change_fcn run (I tried to write: disp('test') in the first row of color_change_fcn function, but it prints nothing.
This seems to be related to your previous question, where you want the two loops to be running simultaneously (well at least appear to be that way).
Building on #Peter's answer, consider the following working example:
function timerDemo()
%# prepare GUI
hFig = figure('Menubar','none', 'Resize','off');
axes('XLim',[0 1], 'YLim',[0 1], 'Visible','off', ...
'Units','normalized', 'Position',[0.1 0.2 0.8 0.6])
hTxt = uicontrol('Style','text', 'FontSize',24, ...
'Units','normalized', 'Position',[0 0.9 1 0.1]);
hPatch = patch([0 0 1 1 0],[0 1 0 1 0],'k');
%# colors to cycle through
c = 1;
clr = lines(4);
%# create timer
delay = 0.5;
hTimer = timer('Period',delay, 'StartDelay',delay, ...
'ExecutionMode','FixedRate', 'TimerFcn',#timerCallback);
%# when figure is closed
set(hFig, 'CloseRequestFcn',#onClose);
%# process images
start(hTimer); %# start timer
for i=1:100
if ~ishandle(hFig), break; end
msg = sprintf('Processing image %d / %d', i, 100);
set(hTxt, 'String',msg)
%# some lengthy operation
pause(.1)
end
if isvalid(hTimer)
stop(hTimer) %# stop timer
delete(hTimer) %# delete timer
end
%# timer callback function
function timerCallback(src,evt)
if ~ishandle(hFig), return; end
%# incremenet counter circularly
c = rem(c,size(clr,1)) + 1;
%# update color of patch
set(hPatch, 'FaceColor',clr(c,:));
drawnow
end
%# on figure close
function onClose(src,evt)
%# stop and delete timer
if isvalid(hTimer)
stop(hTimer);
delete(hTimer);
end
%# call default close callback
feval(#closereq)
end
end
The code simulates running a lengthy processing step on a number of images, while at the same time showing an animation to keep the user entertained.
To keep the code simple, I am showing a patch that updates its color continuously (using a timer). This stands for the animated GIF image of "loading...".
Is this what you want? Just combine the loop bodies.
for i=1:200
if mod(i,2) == 0
set(hAxes,'Color','b');
else
set(hAxes,'Color','g');
end
image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
set(loading1,'string',image2);
drawnow;
end
EDIT: OK, in that case, try a timer instead of the first loop
function output = main_function
% Your other setup calls
hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]);
c = 0;
t = timer('TimerFcn', #color_change_fcn, 'Period', 1.0);
start(t);
for i=1:200
image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
set(loading1,'string',image2);
drawnow;
end
function color_change_fcn
if mod(c,2) == 0
set(hAxes,'Color','b');
else
set(hAxes,'Color','g');
end
drawnow;
c = c + 1;
end
end
Just remember that the MATLAB control flow is inherently single-threaded, so these callbacks won't run if MATLAB is busy working somewhere else.