Adding Second Callback to UIAxes Toolbar in App Designer
10 views (last 30 days)
Show older comments
I'm trying to find out how to add a second callback to the existing toolbar function(s) in App Designer so that one may, for example, hit the Restore View button and have the normal view restore callback as well as a custom function. I found some help here, but I wasn't able to get it to work properly. This was my attempt:
function callback2(app,~)
disp('The button was pushed.')
end
axtoolbar(app.UIAxes,{'export','pan','zoomin','zoomout','restoreview'}) %create toolbar for app.UIAxes
%@(e,d)matlab.graphics.controls.internal.resetHelper(d.Axes,true) %original function for ButtonPushedFcn
ax = app.UIAxes;
ax.Toolbar.Children(5).ButtonPushedFcn = cellfun(@(x)feval(x,app,ax),...
{@(app)matlab.graphics.controls.internal.resetHelper(ax,true),...
@(app)callback2(app)}); %change the restoreview callback to include the original function and my custom function
I don't think this is very difficult to do, but I was in a rush and ended up doing something else anyway. For future reference, this would be beneficial to know though. The version I'm using is 2020b.
3 Comments
Adam Danz
on 16 Mar 2021
app.UIFig = uifigure();
app.UIAxes = uiaxes(app.UIFig);
axtoolbar(app.UIAxes,{'export','pan','zoomin','zoomout','restoreview'}) %create toolbar for app.UIAxes
%@(e,d)matlab.graphics.controls.internal.resetHelper(d.Axes,true) %original function for ButtonPushedFcn
ax = app.UIAxes;
ax.Toolbar.Children(5).ButtonPushedFcn = cellfun(@(x)feval(x,app,ax),...
{@(app,ax)matlab.graphics.controls.internal.resetHelper(ax,true),...
@(app,ax)callback2(app)}); %change the restoreview callback to include the original function and my custom function
function callback2(app,~)
disp('The button was pushed.')
end
Error
Error using myFcn>@(app)matlab.graphics.controls.internal.resetHelper(ax,true)
Too many input arguments.
Error in myFcn>@(x)feval(x,app,ax) (line 7)
ax.Toolbar.Children(5).ButtonPushedFcn = cellfun(@(x)feval(x,app,ax),...
When change the inputs to,
ax.Toolbar.Children(5).ButtonPushedFcn = cellfun(@(x)feval(x,ax,true),...
{@(app,tf)matlab.graphics.controls.internal.resetHelper(ax,tf),...
@(app)callback2(app)});
The error becomes,
Error using matlab.graphics.controls.internal.resetHelper
Too many output arguments.
Error in myFcn>@(app,tf)matlab.graphics.controls.internal.resetHelper(ax,tf) (line 8)
{@(app,tf)matlab.graphics.controls.internal.resetHelper(ax,tf),...
Error in myFcn>@(x)feval(x,app,true) (line 7)
ax.Toolbar.Children(5).ButtonPushedFcn = cellfun(@(x)feval(x,app,true),...
And since resetHelper is in an encrypted p-file, I don't know what the inputs and outputs should be.
Accepted Answer
Adam Danz
on 16 Mar 2021
Edited: Adam Danz
on 16 Mar 2021
First, thanks for the interesting topic (+1).
Here's a simpler way of issuing multiple actions when pressing the Restore toolbar button without hard coding the original callback function which is undocumented, hidden in p-code, and liable to change in the future.
- Get the handle to the Restore button in the axes' toolbar.
- Capture and store the original callback function.
- Overwrite the buttons' callback function by defining a new function where you can execute the original callback function plus do anything else you want. This demo merely shows a uialert to confirm that the axes are restored.
Tested in r2020b and r2021a.
app.UIFig = uifigure();
app.UIAxes = uiaxes(app.UIFig);
axTB = axtoolbar(app.UIAxes,'default');
isRestoreButton = strcmpi({axTB.Children.Icon},'restoreview');
if any(isRestoreButton)
restoreButtonHandle = axTB.Children(isRestoreButton);
originalRestoreFcn = restoreButtonHandle.ButtonPushedFcn;
restoreButtonHandle.ButtonPushedFcn = {@myRestoreButtonCallbackFcn, originalRestoreFcn};
end
function myRestoreButtonCallbackFcn(hobj, event, originalCallback)
% Responds to pressing the restore button in the axes' toolbar.
% originalCallback is a function handle to the original callback
% function for this button.
originalCallback(hobj,event) % Evaluate original callback
fig = ancestor(event.Axes,'figure');
uialert(fig,'Axes restored', 'RestoreButtonCallback', 'Icon', 'info');
end
5 Comments
Juan Millán
on 19 Jan 2023
yes, that's totally true, those are the same functions, but the problem that I'm facing is how to evaluate that function, becouse isn't clear enought to me, what the inputs are, in example:
feval(TargetFun,[],tb)
in results in the following error message:
No public property 'Axes' for class 'AxesToolbar'.
Error in matlab.graphics.controls.internal.ToolbarButtonRegistry>@(e,d)matlab.graphics.controls.internal.resetHelper(d.Axes,true)
Error in APP/Button_2Pushed (line 15317)
feval(TargetFun,[],tb)
Error in matlab.apps.AppBase>@(source,event)executeCallback(appdesigner.internal.service.AppManagementService.instance(),app,callback,requiresEventData,event) (line 63)
newCallback = @(source, event)executeCallback(appdesigner.internal.service.AppManagementService.instance(), ...
Error using internal.matlab.desktop.editor.clearAndSetBreakpointsForFile
Error while evaluating Button PrivateButtonPushedFcn.
So in that order, I would be very thankfully if there any way to solve that concern. I've tried for so long and nothing comes up. Thanks
Adam Danz
on 20 Jan 2023
It looks like you're building your solution from the OP's code which also had problems with feval. My solution doesn't use feval. I suggest you follow the example from my soution instead. If you have questions or problems with that approach, I'd be happy to help.
More Answers (0)
See Also
Categories
Find more on Develop uifigure-Based Apps in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!