Is it possible to use a script as a callback or ButtonDownFcn in uicontrol?
5 views (last 30 days)
Show older comments
Christopher Headley
on 15 Dec 2022
Commented: Walter Roberson
on 16 Dec 2022
What I am trying to do is add a button to a figure CIW and when that button is pressed I want a script to execute. This seems like a very simple task, but the only way I found it to work is by going through functions. I don't see why i should need to go through a function, but this is the only way I have gotten it to work.
What I am trying to do.. Where displayText is a script with 1 line of code: disp('success')
% Add Proceed Button To Figure
pButton = uicontrol(CIW,'Style','pushbutton','Units','pixels',...
'FontName','Tw Cen MT','FontSize',16,...
'String','Proceed','Position',[pBpos,Bdim],...
'ButtonDownFcn', displayText);
What I found that works
% Add Proceed Button To Figure
pButton = uicontrol(CIW,'Style','pushbutton','Units','pixels',...
'FontName','Tw Cen MT','FontSize',16,...
'String','Proceed','Position',[pBpos,Bdim],...
'Callback', @displayText);
function displayText(src,event)
disp('success')
end
Is there a way to execute a script without going through a function?
0 Comments
Accepted Answer
Voss
on 15 Dec 2022
% Add Proceed Button To Figure
pButton = uicontrol(CIW,'Style','pushbutton','Units','pixels',...
'FontName','Tw Cen MT','FontSize',16,...
'String','Proceed','Position',[pBpos,Bdim],...
'Callback', 'displayText');
5 Comments
Walter Roberson
on 15 Dec 2022
Note: When you provide a character vector as a callback, the character vector is executed in the base workspace. Local variables are not available, and neither are nested functions or local functions. That is why you would need displayText.m to exist as a separate file -- because as a separate file is the only way to locate it from the base workspace.
More Answers (1)
Jan
on 15 Dec 2022
'ButtonDownFcn', @(h,e) run('displayText')
8 Comments
Walter Roberson
on 16 Dec 2022
MATLAB has what it calls "workspaces". Those are more or less independent containers with lists of variables and corresponding values. Each time a variable is to be evaluated, it is looked up within the context of a workspace.
There is the "base" workspace, which is the workspace you access at the command line when you are not stopped inside the debugger inside a function. If you are executing code that involves only scripts (and scripts calling other scripts) with no functions involved, then those are all evaluating inside the "base" workspace. If you are executing inside a function, you can deliberately access the base workspace by using evalin('base') and assignin('base')
There is the "global" workspace of variables that can be deliberately shared. There is no evalin('global') or assignin('global') but if you use the global command you can tell your current workspace that any reference to the given name is to work with the global workspace. global variables are not visible inside of functions unless you specifically use global to access them.
There is a workspace for each function. Inside a function, any variable declared as "persistent" is shared by all invocations of the function, and will continue to exist after the function returns, being available the next time the function is run. Inside a function, any variable not marked as persistent or global will be destroyed when the function returns.
The only user-accessible way for one function to look at the local variables of another function, is the very limited evalin('caller') and assignin('caller') that a function can use to interact with the workspace of the function that called it.
Now, suppose you had code something like
function handles = pushbutton1_init(handles)
count = handles.count;
handles.pushbutton1 = uicontrol('style', 'push', 'Callback', 'disp(count)');
end
and suppose that your intention was that every time the pushbutton was called, that the variable count would be displayed. But... as soon as you return from pushbutton1_init, the count that is inside the function workspace for pushbutton1_init would be destroyed. The pushbutton being created will outlive the workspace of the function that creates the uicontrol. If the disp(count) were referring to that variable count then when you pushed the button sometime later it would be trying to display a variable that did not exist.
But in fact when you code a text Callback, the callback is not executed inside the workspace of the function that created the callback: instead the text callback is executed inside the base workspace. The base workspace always exists -- but if the base workspace happens to have a variable count at all then that variable might not happen to have any relationship to the variable you tried to create in pushbutton1_init
What can be done? Well, see http://matlab.wikia.com/wiki/FAQ#How_can_I_share_data_between_callback_functions_in_my_GUI.28s.29.3F . Most of the time, using a text callback is not the best answer. You can use
function handles = pushbutton1_init(handles)
assignin('base', 'count', handles.count);
handles.pushbutton1 = uicontrol('style', 'push', 'Callback', 'disp(count)');
end
and that would do something.
See Also
Categories
Find more on Migrate GUIDE Apps in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!