how to access MATLAB GUI functions from a separate m file - matlab - matlab

i have a function called main(). in this 'main' i call another function A().
i have a GUIde and have a variable 'number' in this.
how can i access 'number' from A() or change the value of 'number' from A()?
1- the code below doesn't work.
main(handles)
%some code
A(handles);
function A(handles)
set(handles.number,0);
end
end
2- and this one doesn't work too.
main(handles)
%some code
A(handles);
function A(handles)
handles.setNumberFnc(5);
end
end
%%%%%in GUI i have this function.
function setNumberFnc(n)
handles.number = n;
guidata(hObject, handles);
i know this function has no 'hObject' i don't know what to do?
3- can i use 'Global number' in GUI and in A()?

You are solving the problem the other way around that I usually do it. For me, the GUI is the main object, and I define my button callbacks and such to call external scripts and functions.
You want to run a seperate script or function which then modifies the GUI. This is fine too! All you need is the handle of the GUI, which you can get, for example, with gcf (assuming the GUI is the currently active figure window). However, your setNumberFcn is a local function (or possibly a nested function, which is almost the same thing), and you cannot call it from a different script or function file. Instead, you would have to put it into your main.m file, in the manner of
function main()
fig_handle = gcf;
numfield_handle = findobj(gcf, 'NumFieldTagThatYouDefinedInGUIDE');
function setNumberFcn(numfield_handle, number)
set(numfield_handle, 'String', num2str(number))
end
end

I've solved my problem.
Only it was necessary to define global the variable 'number' in all the necessary functions. now easily i can change the value of 'number' in GUI or in A() function.
no need to 'set' function.
main()
%some code
A();
function A()
global number;
disp(number);
number = 5;
end
end
and in GUIde:
function B_Callback(hObject, ~, handles)
global number;
number = 2;
guidata(hObject, handles);

Related

Calling sub-function (local function) from another file on Matlab

I'm trying to figure out how to properly call a sub function from another .m file. I've searched for documentation, and only found the way of using function handles (as can be seen here: https://www.mathworks.com/help/matlab/matlab_prog/call-local-functions-using-function-handles.html)
The thing is that I think I've managed to find a way to it without using function handles, and want to know what am i doing and how does it works:
on main.m file:
function main
%function main...
end
function z = sub_function(x,y)
%function sub_function...
end
on outside.m file:
function call_to_local_function_from_outside
z = main('sub_function', x,y);
end
Appernalty, this is working, but I need to know why?

How to create callback function of a uicontrol object which calls the handle object

I have defined an uicontrol pushbutton object and I want to display something in handles when I click on the button. When I try to do that, I get the error Undefined function or variable 'handles'. It does not see the handles or any other object which is in GUI code.
handles.c = 3;
A = uicontrol('Style', 'pushbutton');
A.Callback = display(handles.c)
This code gives the error that I typed above. I may have to give the handle object to the Callback as input but I don't know how to do.
Thanks in advance.
In order to access the handles data structure often referred to in MATLAB's UI documentation, you have to use guidata to set new values and retrieve existing values when in a callback.
So from anywhere, if you want to set the value you'll want to do something like:
handles.c = 3
% Replace `gcf` with the explicit handle to your figure if possible
guidata(gcf, handles)
Then inside of your callback, you can get the current guidata the following way:
function callback(src, event)
handles = guidata(src);
display(handles.c)
end
And then assign this function as the callback to your uicontrol
A = uicontrol('Style', 'pushbutton', 'Callback', #callback);
If you don't want to create a separate callback function and instead insist on a one-liner, you could create an anonymous function to accomplish a similar task
A.callback = #(src, evnt)display(getfield(guidata(src), 'c'))
As you can see, the explicit function is a little easier to understand

How to access variables from base workspace within function?

I am a nested function inside a function and I am calling variables from base workspace. Note that guiel is in base workspace.
function callback(~,~)
vars.dropheight = str2num(get(edit(2),'String'));
vars.armradius = str2num(get(edit(1),'String'));
kiddies = get(guiel.hAX(3),'Children');
delete(kiddies);
clear kiddies;
set(guiel.tfPanel,'Visible','off','Position',cnst.tfPanelpos);
set(guiel.hAX(1),'Position',cnst.axpos1);
if ishandle(guiel.hAX(2))
set(guiel.hAX(2),'Position',cnst.axpos2);
end
eval(get(guiel.hPB(4),'Callback'));
end
The best way, in my opinion, is to store guiel into guidata.
guidata(hFig, guiel); % hFig can be gcf for top figure
and access it in callback by
guiel = guidata(hFig);
One of the alternatives is to pass the variable as input to callback by defining it as
{#callback, guiel}
The callback function definition will be
function callback(~, ~, guiel)
If you really hate these methods, a simple way is to define it as global in base and your callback. But this is something one tries to avoid for both performance and code maintainability consideration.
Best practices for GUI design are that you encapsulate your GUI and its operations in such a way that it never has to depend on the base workspace to function correctly. The reason? The user and other programs can modify anything in the base workspace, and can thus easily break your GUI.
I give an example of a basic GUI setup using nested functions in this post. Here's a general skeleton for designing a GUI:
function create_GUI()
% Initialize data:
data1 = ...;
data2 = ...;
% Create GUI:
hFigure = figure;
hObject1 = uicontrol(..., 'Callback', #callback1);
hObject2 = uicontrol(..., 'Callback', #callback2);
....
function callback1(~, ~)
% Access any data or handles from above
...
end
function callback1(~, ~)
% Access any data or handles from above
...
end
end
The idea is that the main function creates all the GUI components, initializing all the needed data and object handles. The callbacks nested within the main function will have access to the data and handles as needed. I suggest designing your GUI like this, or using one of the other options listed here. This should alleviate some of your data access issues and make your GUI more robust.

MATLAB : GUI pushbutton call function .m

I have some functions create on matlab (.m). And I would like to call them on an interface GUI : how my push button callback function can call a function .m (which is in the same workspace) ?
Moreover, my function returns some variables so I would like to keep these variables in my workspace in order to access them from other buttons of my interface.
And after, is it possible to put the result of a variable on my interface ?
Thank you in advance,
Best regards
Yes it's possible and is quite simple.
You can call your .m file directly in the pushbutton callback and fetch the results as you would in any other script.
Let's consider a simple example in which you call function A from the callback. Let's say function A outputs 2 arguments, out1 and out2.
In the .m file of function A, the function is defined as follows (input arguments can be anything of course):
function [ou1,out2] = A(Input arguments)
%// code here
end
Then in the pushbutton callback in your GUI, use this syntax to retrieve the outputs of function A and use them:
[B,C] = A(Input arguments); %// Or out1 and out2, the names don't matter here.
Better yet, to share those data with other callbacks from your GUI, you can store the variables in what is called guidata, or the data associated with the GUI. There is a convenient handles structure used to store any kind of data and easily share them between callbacks.
Therefore, in your case you would use:
[handles.B, handles.C] = A(Input arguments)
and as such handles.B and handles.C are accessible from any callback in your GUI. Don't forget to update the handles structure at the end of the callback with this command:
guidata(hObject,handles)
where hObject is the handles to the GUI's figure. For more info about that check the docs here.

Use the output of a callback further in the code

I have a subroutine in my code where I create a GUI for the user to chose a type of analysis:
%% Gives user the choice of replacement method
figure('Units','Normalized','Color','w','Position',[.3 .6 .4 .15],...
'NumberTitle','off','Name','Analysis choice','MenuBar','none');
uicontrol('Style','text','Units','Normalized',...
'Position',[.1 .7 .8 .2],'BackgroundColor','w','String','What replacement method do you want to use?');
uicontrol('Style','pushbutton','Units','Normalized',...
'Position',[.05 .3 .3 .3],'String','Cubic interpolation 24 points',...
'CallBack','cubic_choice'); % cubic_choice.m rotine must be on current folder
uicontrol('Style','pushbutton','Units','Normalized',...
'Position',[.4 .3 .3 .3],'String','Last good data value',...
'CallBack','lgv_choice'); % lgv_choice.m rotine must be on current folder
uicontrol('Style','pushbutton','Units','Normalized',...
'Position',[.75 .3 .2 .3],'String','Linear interpolation',...
'CallBack','li_choice'); % li_choice.m rotine must be on current folder
uiwait;
close;
Further in the code, I have a if loop that analysis the choice that the user made:
if strcmp(inp,'cubic') ...
The problem is, when I press the button "Cubic interpolation 24 points", the callback function doesn't give me the inp variable, i.e., it doesn't appear on the workspace.
The callback function is something like this:
%% Callback script for replacement method
% Cubic interpolation with 24 points method
function [inp] = cubic_choice
inp = 'cubic';
uiresume(gcbf); % resumes the button call
i know that I probably have to use setappdata and getappdata because I already read it in some other thread but I can't get it to work.
Can anyone help me?
Thanks in advance.
Kind regards,
Pedro Sanches
Rather than using a global variable, you imho should check the functions getappdata, setappdata and / or guidata.
Basically, from your callback, you'll have to set your choice at some place you can access it in the rest of the code.
One possibility e.g. is to use set/getappdata as follows:
function cubic_choice()
figHandle = ancestor(gcbf, 'figure');
setappdata(figHandle, 'choice', 'cubic');
uiresume(gcbf);
end
Right after your uiwait call you can then get this property, taking figHandle from the return-value of your figure-call in the first line of your example:
inp = getappdata(figHandle, 'choice');
This is an issue of variable scope and design. inp will not be visible outside the callback function. You are also not "returning it to the workspace" because it is the GUI that is calling you back; no assignment takes place in the workspace.
You could declare global inp both in your workspace and in the callback function, as in
function [inp] = cubic_choice
global inp
inp = 'cubic';
However, you may want to consider responding to the choice directly from within the callback handler. This means, whatever code you have in your if-statement may just as well go directly into your callback function.
Alternatively, if it is really about choices, why not use radio buttons? Then, you could hold on to he handle h returned by uicontrol and query it's state at any later time with get(h, 'value').