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.
Related
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.
I'm working at GUI in MATLAB application.
I use uitable object. Then I find interesting undocumented feature how to sort it's data, select whole row and etc.
I do this way:
% create jhandle to my uitable object
juiTable = findjobj(handles.uitable1,'class','UIScrollPane');
jtable = juiTable(1).getComponent(0).getComponent(0);
%... some my action like this:
jtable.setRowSelectionAllowed(true);
%...
%and now lets try use callback for selected cell in uitable:
juiFunHandle = handle(jtable, 'CallbackProperties');
set(juiFunHandle, 'MousePressedCallback', #CellSelectionCallback);
set(juiFunHandle, 'KeyPressedCallback', #CellSelectionCallback);
That works perfectly.
Now question: how to put multiple parameters to CellSelectionCallback?
I want this function makes some action (makes some button active etc).
For this I try to put GUI handles to it. But how?
My CellSelectionCallback function:
function CellSelectionCallback(juiTable, varargin)
% get it from the example
row = get(juiTable,'SelectedRow')+1;
fprintf('row #%d selected\n', row);
P.S. I see varargin into it. So can I use multiple arguments? How to put it using my set function??
By default, MATLAB callbacks pass two input arguments (the objec that generated the callback and some event data). If you want to pass more (or fewer) arguments to your callback, you can use an anonymous function to accept these two inputs and then call your callback with the desired inputs.
In your case, you could write your anonymous function such that you pass the handles object as an additional input to your callback function
set(juiFunHandle, 'MousePressedCallback', ...
#(src, evnt)CellSelectionCallback(src, evnt, handles));
Then your callback would look something like:
function CellSelectionCallback(jtable, evntdata, handles)
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);
I am relatively new to MATLAB so forgive me if this is rather basic question. I am trying to understand how to manipulate variables and pass the results between functions within the GUI.
If I set up the GUI using the GUIDE interface I get several functions. I would like to do a certain action when I click a pushbutton, save a variable, then use that variable in another function.
function pushbutton1_Callback(hObject, eventdata, handles)
handles.MyData = 7;
Now, since that data is stored in handles can I not simply use this in another function within the GUI in this fashion?
function pushbutton2_Callback(hObject, eventdata, handles)
result = 5 + handles.MyData;
This is a really simple example, but I am trying to get down to the logic of how to pass variables. I know there is a lot of information out there and I have read it but I cannot get down to the logic of how the variables are stored in the structure and how they can be passed between functions.
When you update the handles struct, you have to store it using guidata:
guidata(hObject, handles);
Then you can use it in a different callback.
I am struggling to use axes on my GUI because it says it is not defined. Here is the summary of the code :
function bitirme_OpeningFcn(hObject, eventdata, handles, varargin)
axes(handles.axes1)
imshow('photo1.jpg');
...
function pushbutton1_Callback(hObject, eventdata, handles)
theta=inverseKinematic(...)
...
function [Theta1,Theta2]=inverseKinematic(angle1,angle2,angle3,desCorX,desCorY)
axes(handles.axes1);
....
plot(a,b);
....
Until the function inverseKinematic is called,everything works fine. However when it is called, the image doesn't turn to be a graphic and I see the error " Undefined variable "handles" or class "handles.axes3" " on matlab command window. Why can I not call axes(handles.axes1) in a nested function? What is the reason behind it?
Each function has its own workspace, and callbacks generated by GUIDE share data associated with what is called the handles structure. Every components of the GUI (axes, pushbuttons, etc.) are associated with the figure in which they are located. Hence GUIDE already provides the callback functions with everything stored in the handles structure.
However, nested functions do not have implicit access to the data stored in the handles structure. You need to specifically provide those data to the functions. There are a couple options available, for example:
1) Provide the handles structure as an input argument to the function.
2) Use getappdata and setappdata functions to associate data with a figure or MATLAB's root
3) Retrieve the handles structure "by hand" at the very beginning of the nested functions like so for example:
function [Theta1,Theta2]=inverseKinematic(angle1,angle2,angle3,desCorX,desCorY)
handles = guidata(gcf)
axes(handles.axes1);
....
plot(a,b);
....
%// Save the changes made to the handles structure.
guidata(handles to the figure,handles);
where gcf refers to the current figure. You can actually use the name of the figure or hObject.
Note that when using the command plot, you don't need to set the current axes before each call. You can use the Parent property inside the call to plot to select where to plot the data.
Example:
plot(a,b,'Parent',handles.axes1)
I hope that was clear enough!