I am new of Matlab GUI and i have the following problem.
I have declared a slider control and his properties, and i have added a listerner to the callback and to the PostSet event handler (i think that it is tecnically called event handler) as you can see below:
function [] = HandlerSlide()
%HANDLERSLIDE Summary of this function goes here
% Detailed explanation goes here
clf;
due = '2';
hSlider = uicontrol( ...
'Style','slider', ...
'Callback',#(s,e) disp(['hello ',num2str(due),' asdad']),...
'Position', [400 30 200 20] ... %[x,y, widht, height]
);
hListener = addlistener(hSlider,'Value','PostSet',#pippo);
end
function [] = pippo(s,e)
disp('ciao');
end
As you can see i have used parameter "due" in the Callback handler (the anonymous function). Now i would like to pass parameter to use in the "pippo" function without declare it as anonymous function. Is it possible?
In other words i would like to declare "hListerner" like this:
hListener = addlistener(hSlider,'Value','PostSet',#pippo{parameter1,parameter2, etc ...});
function[] = pippo(s,e, parameter1, parameter2, etc ...)
Beside how can i use in the main the value returned by "pippo"?
thank you in advance :D
Inputs in handle functions are added like that:
hListener = addlistener(hSlider,'Value','PostSet',{#pippo,parameter1,parameter2});
You have to be careful then in the function, as "parameter1" won't be the first input but the third (after source and eventdata).
Related
I am making an app to track my finances and I am confused as how to pass a string to a callback function in a uicontrol pushbutton object.
For instance:
classdef moneyapp < handle
methods (Access = public)
function app = moneyApp
% uicontrol object example
app.NewSymbolGLMC = uicontrol(app.FigureGLMC,...
'Style','pushbutton','Position',[300 60 200 20],...
'String','New Stock',...
'Callback', {#app.newStock,'Account Name'});
end
function newStock(src,eventData,account)
% Do something with the string, 'Account Name'
end
end
end
end
I am confused as to how to get the string, 'Account Name', to the newStock function. This is an essential part to my code and I just think my syntax is not correct; more examples of the code can be provided if needed. Any help would be greatly appreciated!
Since newStock is a method of your class, the first input must be the object itself. Because of this you need four input arguments in your function definition:
the instance, the source and event data (the default inputs), and the account name.
function newStock(obj, src, eventData, account)
As a side note, the capitalization of your constructor (moneyApp) must match the capitalization of the class (moneyapp) to be treated as a constructor.
I have a function defined like the following in a .m file:
function main_fn()
...
end
function sub_fn1()
...
end
function sub_fn2()
....
end
...
function sub_fnN()
...
end
i.e. standard structure with main function first followed by subfunctions accessible by the main function when it is called.
I know that you can use whos within the function calling environment to return the variables stored in the function call stack. I would like to retrieve the sub-functions defined within the function file, and return them as a cell array of function handles.
Is this possible?
EDIT: the answer by #nirvana-msu has made my original request possible. However, now I find that it is more convenient to store these functions in a struct, so that I can refer to them by name:
For example:
fcn =
struct('sub_fn1', #sub_fn1, ...
'sub_fn2', #sub_fn2, ...
...
)
EDIT 2:
It is simply to convert the cell array obtained in the answer to a struct, simply use func2str:
fcns = cell2struct(fncs, cellfun(#func2str, fncs, 'uni', 0));
Use localfunctions - introduced in R2013b:
function main_fn()
fcns = localfunctions();
end
function sub_fn1()
end
function sub_fn2()
end
function sub_fnN()
end
It returns a cell array of function handles to all local functions in your file:
fcns =
#sub_fn1
#sub_fn2
#sub_fnN
My goal is to get the user's input from a uicontrol text box, do operations on the input and then display the output to another text box. MATLAB gives me the error:
Error using
UnitConverter/lbs2kg
Too many input arguments.
Error in
UnitConverter>#(varargin)app.lbs2kg(varargin{:})
(line 22)
'Callback',#app.lbs2kg,'String',app.inputMass);
Error while evaluating UIControl Callback
Here is my code:
classdef UnitConverter < handle
properties
Figure % Graphics handles
DispInputMass
DispOutputMass
inputMass %Variables/Class Properties
outputMass
end
methods
function app = UnitConverter
% This is the "constructor" for the class
% It runs when an object of this class is created
app.Figure = figure('Name','Unit Converter') ;
app.DispInputMass = uicontrol('Style','edit',...
'Callback',#app.lbs2kg,'String',app.inputMass);
app.DispOutputMass = uicontrol(app.Figure,'Style','edit','Position'...
,[168 100 47 26],'String','kg');
end
function lbs2kg(app,evt)
app.inputMass = get(app.DispInputMass,'string');
app.outputMass = app.inputMass*.453;
set(app.DispOutputMass,'string',app.outputMass);
end
end
end
The callback method actually has 3 inputs - MATLAB is throwing this error because it is trying to send three inputs to your callback which is written to only accept 2. The 3 inputs are (in order): the main object (app), the object sending the event (uicontrol) and the event (matlab.ui.eventdata.ActionData).
You can change the code to the following to get it to work:
function lbs2kg(app, obj, evt)
app.inputMass = get(app.DispInputMass,'string');
app.outputMass = app.inputMass*.453;
set(app.DispOutputMass,'string',app.outputMass);
end
Additionally you can change the first line of the function to the following:
function lbs2kg(varargin)
Breakpoint the code at the first line of the callback and investigate the contents of varargin. For more help about varargin see here (http://www.mathworks.com/help/matlab/ref/varargin.html)
In matlab if I've a context menu with handle cxmenu_Options which is linked to different three uicontrol objects.
Inside the context menu callback function:
Code Demo:
function demoOnContextMenus
hFigure = figure;
hControl = uicontrol( ...
'Parent' , hFigure , ...
'Style' , 'Edit' , ...
'Position' , [200 200 180 40] , ...
'Tag' , 'IamControl' , ...
'String' , 'UI-Control');
hCxMenu = uicontextmenu( ...
'Tag' , 'IamMenu' , ...
'Callback',#CxMenuCallback);
set(hControl,'UIContextMenu',hCxMenu);
function CxMenuCallback(objectHandle,eventData)
tag = get(gcbo,'tag');
helpdlg(tag);
end
end
How Can I get the handle of the uicontrol which the context menu has been called from ?
There are two ways to access the handle:
gco returns the handle of the currently selected object. Thus tag = get(gco,'tag') will return IamControl.
Alternatively, you can pass the handle directly to the callback (in case the hierarchy becomes more complicated, since gco will only give you the top-level handle of the eventual chain):
handleToPass = hControl;
hCxMenu = uicontextmenu( ...
'Tag' , 'IamMenu' , ...
'Callback',#(oh,evt)CxMenuCallback(oh,evt,handleToPass));
set(hControl,'UIContextMenu',hCxMenu);
function CxMenuCallback(objectHandle,eventData,handleOfCaller)
tag = get(handleOfCaller,'tag');
helpdlg(tag);
end
Using Matlab's guide environment I have found another way to determine the caller.
The command gco (get current object) simply did the job.
In my case the context menu provides the option to open a path specified in an "Edit Text" object in Windows Explorer.
function open_in_browser_Callback(hObject, eventdata, handles)
cur_obj=gco;
cur_path=get(cur_obj,'String')
if(~isempty(cur_path))
winopen(cur_path);
end
With this solution I was able to use the same context menu for two "Edit Text" objects.
Working on an assignment involving Genetic Algorithms (loads of headaches, loads of fun). I need to be able to test differing crossover methods and differing mutation methods, to compare their results (part of the paper I have to write for the course). As such, I want to just pass the function names into the Repopulate method, as function handles.
function newpop = Repopulate(population, crossOverMethod, mutationMethod)
...
child = crossOverMethod(parent1, parent2, #mutationMethod);
...
function child = crossOverMethod(parent1, parent2, mutationMethod)
...
if (mutateThisChild == true)
child = mutationMethod(child);
end
...
The key point here is like 3, parameter 3: how do I pass mutationMethod down another level? If I use the # symbol, I get told:
"mutationMethod" was previously used as a variable,
conflicting with its use here as the name of a function or command.
If I don't use the # symbol, then mutationMethod gets called, with no parameters, and is quite unhappy.
While I am aware that yes, I could just rewrite my code to make it work differently, I'm now curious as to how to make it actually work.
Any help is greatly appreciated.
Actually just dont use the # symbol, use it when you call the Repopulate function instead.
Example:
function x = fun1(a,m)
x = fun2(a,m);
end
function y = fun2(b,n)
y = n(b);
end
which we call as:
> fun1([1 2 3], #sum)
6
Refer to the documentation for Passing Function Handle Arguments
Note you can check if the argument is a function handle by: isa(m,'function_handle'). Therefore you can make your function Repopulate more flexible by accepting both a function handle and a function name as a string:
function x = fun(a,m)
if ischar(m)
f = str2func(m);
elseif isa(m,'function_handle')
f = m;
else
error('expecting a function')
end
x = fun2(a,f);
end
which now can be called both ways:
fun1([1 2 3], #sum)
fun1([1 2 3], 'sum')