Adding Second Callback to UIAxes Toolbar in App Designer

조회 수: 19 (최근 30일)
Cameron B
Cameron B 2021년 3월 15일
댓글: Adam Danz 2023년 1월 20일
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
Cameron B
Cameron B 2021년 3월 16일
Sorry, I had posted the wrong version of code. I've since updated it, thanks.
Adam Danz
Adam Danz 2021년 3월 16일
Thanks, Cameron B but now I'm getting this error in r2020b and 21a,
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.

댓글을 달려면 로그인하십시오.

채택된 답변

Adam Danz
Adam Danz 2021년 3월 16일
편집: Adam Danz 2021년 3월 16일
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.
  1. Get the handle to the Restore button in the axes' toolbar.
  2. Capture and store the original callback function.
  3. 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
Juan Millán
Juan Millán 2023년 1월 19일
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
Adam Danz 2023년 1월 20일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Visual Exploration에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by