How to assign a class method as a ClickedCallback?

조회 수: 7 (최근 30일)
Dominik Mattioli
Dominik Mattioli 2020년 1월 8일
답변: Steven Lord 2020년 1월 14일
The class may change, but the method names are the same.
classdef BaseClass < handle
properties
p = []
end
methods
function h = get_save_handle( obj )
h = @obj.save;
end
end
end
classdef Class1 < BaseClass
properties
p1 = []
end
methods
function save( obj )
% ...
end
end
end
classdef Class2 < BaseClass
properties
p2 = []
end
methods
function save( obj )
% ...
end
end
end
I need to change the callback of a save button in my UI depending on the user's data, which will determine which class is used. So if I'm using class1, the ClickedCallback of my save button needs to be class1.save(), etc. Here is how I assign the callback:
switch data_type
case 'Class1'
save_data = Class1();
case 'Class2'
save_data = Class2();
end
saveUIButton.set( 'ClickedCallback', { save_data.get_save_handle(), f }, 'UserData', save_data ) % 'f' is my figure.
But when I click the save button, the varargin{:} causes an error because the 'save' function arguments aren't compatible:
Error using Class1/save
Too many input arguments.
Error in BaseClass>@(varargin)obj.save(varargin{:}) (line 82)
h = @obj.save;
Error while evaluating PushTool ClickedCallback.
  댓글 수: 3
Mohammad Sami
Mohammad Sami 2020년 1월 14일
Most likely its because the button will pass itself and the event variables in the callback. So you need to add more variables to your save function. If you don't need them in your callback you can use ~ to replace the variable in the function signature.
function save( obj , ~ , ~)
Dominik Mattioli
Dominik Mattioli 2020년 1월 14일
편집: Dominik Mattioli 2020년 1월 14일
These are valid workarounds, but not exactly what I was looking for.
I ended up just using polymorphism and not changing the callback function, which I suppose is the cleaner thing to do anyhow.
function save_button_callback( hObject, eventData, figureHandle )
data = hObject.get( 'UserData' );
data.save();
end
where, data is one of the derived classes. Just need to make sure that the save button's UserData is properly assigned.

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

채택된 답변

Steven Lord
Steven Lord 2020년 1월 14일
methods
function h = get_save_handle( obj )
h = @obj.save;
end
end
The name of the method is save.
methods
function h = get_save_handle( obj )
h = @save;
end
end
When that function handle gets executed, MATLAB will use the input arguments with which it was called to determine which function or method named save will be called. If the input isa Class1 the Class1 save method will be called. If it isa Class2 then Class2's save method will be called. If it's neither, the built-in save function will be called.
For example:
h = @plot; % No class information required to create h
% Sample data
g = graph(bucky);
x = 1:10;
figure
h(g) % the plot method for graph objects gets called
figure
h(x) % the built-in plot function (for double data) gets called
HOWEVER, I would be wary about overloading save for your objects, as it has kind of an important meaning already in MATLAB. If you're looking to customize what happens when you save your objects, you probably want to overload the saveobj and loadobj functions instead as described in this topic in the documentation. If your save method is intended to do something like writing the data to some other type of file rather than a MAT-file, I'd suggest a slightly longer and more descriptive name, something like saveTo<fileType>File (saveToTextFile or saveToTXTFile as an example.)

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Migrate GUIDE Apps에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by