How to detect the close window event for a "bar" graph
Mostra commenti meno recenti
I tried to use the CloseRequestFcn to specify the close action for a bar graph but it does not work. It seems that it only works for figures.
How can I detect the user action of closing a bar graph window and change its behavior?
Thanks in advance for your help!
Risposte (1)
To invoke an action when the bars are deleted, use the DeleteFcn property of the bar object. Bars can be deleted using cla(), delete(h) where h is the bar handle, or when the figure closes.
The CloseRequestFcn is invoked when the figure closes which will also invoke the DeleteFcn if the bars still exist. See a demo in the comments below this answer.
22 Commenti
Adam Danz
il 4 Set 2020
'Is closing the bar figure window and deleting the bars the same thing?"
No. Closing the figure invokes the figure's CloseRequestFcn as well as the bars' DeleteFcn but if you clear the axes or delete the bar objects without closing the figure, the DeleteFcn will be invoked but not the CloseRequestFcn.
Example:
fig = figure();
fig.CloseRequestFcn = @(~,~)fprintf('Fig close req called!\n');
h = bar(1:5);
h.DeleteFcn = @(~,~)fprintf('Bars deleted!\n');
now execute the command below to clear the axes and watch the Command Window.
cla()
now try to close the figure and watch the command window
close(fig)
Notice that the figure didn't close because now it has no function to close it! To close it,
close(fig, 'force')
Adam Danz
il 4 Set 2020
Your callback function is not working because it has no idea what "s1" is. That variable needs to be passed into the function. Also, don't use gcf when you have access to the figure's handle.
h = bar(x, data(2:11), 'DeleteFcn',@my_closereq);
function my_closereq(src,event,c)
% Close request function
delete(ancestor(src, 'figure'))
clear(c)
end
Walter Roberson
il 8 Set 2020
fig.CloseRequestFcn = @(){fprintf('Fig close req called!\n'); close(fig); clear s1;}
Adam Danz
il 8 Set 2020
That's not how to write a close request function. Model it after the DeleteFcn I provided above or the closeRequestFcn provided in the documentation.
Chao
il 8 Set 2020
Chao
il 8 Set 2020
Walter Roberson
il 8 Set 2020
It depends what you want to do. Do you want the special action to be invoked only when the user clicks the X to delete the entire figure? If so then that is what CloseRequestFcn can do for you. But if you want the special action to be invoked in other circumstances, such as cla() or if the user plots something else, then DeleteFcn would be the better hook.
CloseRequestFcn is not invoked if you ask to close() a figure, or any other code action that might delete a figure: it is only invoked as the UI action of the user requesting to close the figure.
Steven Lord
il 8 Set 2020
The user doesn't delete the bar chart when they close the figure window.
MATLAB will automatically delete all the graphics objects in the figure window when the figure is closed. If some or all of those graphics objects have DeleteFcn properties that are populated, it will invoke the functions stored in those properties.
theFile = tempname;
fid = fopen(theFile, 'wt');
h = bar(1:10);
h.DeleteFcn = @(varargin) fclose(fid);
counter = 0;
while ~isempty(fopen(fid)) % the file is still open
fprintf(fid, '%d\n', counter);
counter = counter + 1;
pause(1)
end
Let MATLAB wait for a couple seconds, then close the figure (which will close the file that we opened with fopen.) Look at the contents of the file:
edit(theFile)
Close it, wait a couple seconds, and reopen it. You should see that no one has written to it since the body of the while loop stopped executing.
A note on the DeleteFcn in the example above: we're not using any of the inputs with which MATLAB calls the DeleteFcn. So we just accept as many as MATLAB passes in (with varargin) and ignore them.
"BTW, how do you even trigger the "DeleteFcn" in your example above?"
My answer explains how the DeleteFcn is triggered: "Bars can be deleted using cla(), delete(h) where h is the bar handle, or when the figure closed".
So, if you're clearing the axis to restart the bar plot, use the DeleteFcn. If you're closing the figure you can use either the DeleteFcn or the CloseRequestFcn.
Clever to use varargin for the ignored callback inputs. I usually use @(~,~)myFun(__) but varargin is more flexible.
Chao
il 9 Set 2020
Adam Danz
il 9 Set 2020
CloseRequestFcn which is a propery of the figure.
Steven Lord
il 9 Set 2020
So if a user clears the axes (using the cla function, which will delete the bar graph but leave the figure intact) or deletes the bar graph without closing the figure in some other way (turning hold off and plotting something new in the axes, for instance) you don't want the serial port to be closed?
Adam Danz
il 9 Set 2020
That's a good question Steven is asking.
If the answer is no (ie you don't want the port to be closed when the axis is cleared), I wonder how you're generating the bar plots. The most efficient way to update the bar plot is to plot it once and only once and then update the YData and any other properties every time data arrives. In that case, you probably want to use the DeleteFcn so the serial port is closed after the bar handle is deleted. Of course you could have a condition that tests for a valid handle and recreate the bar graph if it's deleted.
But if you're clearing the bar graph completely and regenerating it every time data arrives, that's very inefficient and slow.
Walter Roberson
il 9 Set 2020
Have you considered using onCleanup() to close the serial port?
Steven Lord
il 9 Set 2020
I'd considered suggesting onCleanup as well, but in order for it to trigger when the figure was closed (as the poster said was their goal) they'd need to store it somewhere that Goes Away when the figure gets closed like the UserData property of the figure. But if you're going to do that why not use the figure property that's dedicated for this sort of thing, the CloseRequestFcn?
Chao
il 9 Set 2020
Modificato: Walter Roberson
il 9 Set 2020
Walter Roberson
il 9 Set 2020
They are looping inside a function; they can make the onCleanup a local variable of the function. If the function ever terminates, the cleanup will happen automatically.
Adam Danz
il 9 Set 2020
@Chao just for future reference, when you override the close request function, you must explicitly close the figure within the callback function if want it to close.
For example,
f = figure();
f.CloseRequestFcn = @closeFigureFcn;
function closeFigureFcn(h,~)
fprintf('\n\nGoodbye!\n\n')
delete(h) % <-- delete figure
end
Also, if you have the figure handle, you can delete the figure at any time using delete(f) even if its closeRequestFcn is otherwise blocking its closure.
Chao
il 9 Set 2020
Categorie
Scopri di più su Discrete Data Plots in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!