Adding Second Callback to UIAxes Toolbar in App Designer
10 ビュー (過去 30 日間)
古いコメントを表示
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 件のコメント
Adam Danz
2021 年 3 月 16 日
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
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.
- 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 件のコメント
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
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 Center および File Exchange で Develop uifigure-Based Apps についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!