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)
Related
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
I need to process an image based on where the user is clicking using Matlab Gui. I have found examples which suggest to use the ButtonDownFcn like this:
function buttonSelectSuperpixels_Callback(hObject, eventdata, handles)
h = handles.myCanvas;
set(h,'ButtonDownFcn',#position_and_button);
and then process the clicked points in the subfunction position_and_button like this:
function position_and_button(hObject,eventdata)
Position = get( ancestor(hObject,'axes'), 'CurrentPoint' );
Button = get( ancestor(hObject,'figure'), 'SelectionType' );
However I would need to process some other variables in that last subfunction. Is it possible to pass the handles variable to position_and_button and also update it?
I tried to just pass handles as an argument but it doesn't seem to work.
You can pass the handles struct to your callback by adding it as an input using either an anonymous function
set(h, 'ButtonDownFcn', #(src, evnt)position_and_button(src, evnt, handles))
Or a cell array
set(h, 'ButtonDownFcn', {#position_and_button, handles})
The issue though, is that MATLAB passes variables by value rather than by reference. So when you define these callbacks, they will make a copy of handles as it looks when the callback is created. It is this copy that will be passed to the other function. Additionally, any changes that you make to handles within your callback are made to yet another copy and no other function will ever see these changes.
To avoid this behavior, you can retrieve the handles struct from the guidata within your callback (ensuring you have the most up-to-date version). Then, if you make any changes to it, you would then need to save the guidata after these changes and all other functions will be able to see these changes.
function position_and_button(src, evnt)
% Get the handles struct
handles = guidata(src);
% Now use handles struct however you want including changing variables
handles.variable2 = 2;
% Now save the changes
guidata(src, handles)
% Update the CData of the image rather than creating a new one
set(src, 'CData', newimage)
end
In this case, you would only need to specify the default two inputs to the callback function.
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.
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!
Inside of one parent function, I have a callback function related to a button on a gui.
When the button is pressed, one of the things it does is define a variable (let's say X) that needs to be persistent so that later on, another sub function to the parent function can use X.
(i.e. callback functionA creates variable X.
later on, functionB requires variable X to be known, to know a specific path to take)
Is there any way to go about this?
I've read up on using handles to pass it to the second function, but I can't seem to figure out a way to do this.
Indirectly from Matlab guidata documentation:
in the first callback function:
function first_Callback(hObject, eventdata, handles)
% add some additional data as a new field called x
handles.x = 1;
% Save the change you made to the structure
guidata(hObject, handles)
in the second callback function simply use handles.x because handles is already passed as a parameter to the second callback, if they belong to the same parent figure.
function second_Callback(hObject, eventdata, handles)
% a will have the value 1
a = handles.x;
Note: Even though you are saving handles to hObject (which is the current object that has called the callback function), the handles structures is visible to other objects on the same figure. Saving handles structure to hObject and saving to the parent figure are virtually the same. Also you only need to use guidata if you make changes to the handles structure. If you only read the value of a handles member, you don't need to save it after that.