I have GUI1 that opens GUI2.
I want GUI2 to execute a function from GUI1.
This link shows how to execute a callback, but i want to execute a function.
Thanks
You need to create a handle to that function and save it somewhere where it can be assessed.
e.g. in the GUI1 opening function (where hObject is GUI1 figure object/handle):
func.myFun1=#myFun1;
func.myFun2=#myFun2;
setappdata(hObject,'fun_handles',func);
then, in GUI2, you can recover the handles with func=getappdata(GUI1_figure,'fun_handles');, where GUI1_figure is GUI1 figure object. The figure object can be either saved when the GUI is greated (e.g. if GUI2 is always created from GUI1, pass the object as an argument and save it somewhere) or found with something like findobj(0,'-depth',1,'Tag','tag_of_GUI1_figure')
Related
I have a GUI called GUI_main in which I have a pushbutton called pushbutton_GUI_main. I currently have the following callback function implemented:
function pushbutton_GUI_main_Callback(hObject, eventdata, handles)
GUI_sub
Where GUI_sub is another GUI that opens when you click on pushbutton_GUI_main. However, I want something like the following:
function pushbutton_GUI_main_Callback(hObject, eventdata, handles)
if (GUI_sub == open)
close(GUI_sub)
else
GUI_sub
That is, with pushbutton_GUI_main I want to be able to open and close GUI_sub.
You need an object handle to reference the sub GUI. Assuming GUI_sub is a GUI built with GUIDE, it is programmed by default with an optional handle output.
A naive implementation for a GUIDE GUI would look something like this:
function pushbutton1_Callback(hObject, eventdata, handles)
if ~isempty(handles.figure1.UserData)
close(handles.figure1.UserData);
handles.figure1.UserData = [];
else
handles.figure1.UserData = sub_GUI;
end
Most of (maybe all?) MATLAB's graphics objects have a UserData field by default. I've utilized the UserData of the base figure object for this simple example. See also: Share Data Among Callbacks for other methods to store/transfer this data.
As excaza says, handles is a great way to pass data or information in a GUI.
Another way, if you for some reason don't want to store the GUI handle, perhaps if the GUI_sub could be created independently is to search for the figure handle.
subGuiH = findall(0,'Name','GUI_sub');
if ~isempty(subGuiH)
close(subGuiH);
end
GUI_sub;
The search could be narrowed by adding
findall(0,'Type','figure','Name','GUI_sub')
Depending on your Matlab version, you could also checkout groot
My Matlab GUI is a form with many text fields that are initially populated using the same data struct. Each text field has a callback and a create function, where the text field is assigned the value of the given struct. However, at some later point I would like to repopulate the form using a different struct, as an event triggered by pressing a push button. The code looks approximately like:
h = MyFigure;
global mystruct
mystruct = somevalues;
handles = guidata(h);
set( handles.textfield1, 'String', mystruct.value1 )
...
set( handles.textfieldN, 'String', mystruct.valueN )
However, if I could make Matlab call all these callbacks recursively (like a "validate tree" function), I wouldn't have to call "set" for each text field. I have tried refresh(h) and drawnow(), with no luck.
Now my question is whether or not there is such a function built into the matlab guide framework?
When you set a property of a handle like set(h,'String',str), the value of str is copied. It is not a reference to that variable that can be updated automatically. Your best bet is to make a subroutine called updateText or something like that, put all of the set statements in it, and call it when needed.
Calling guidata(hObject, handles); is only for updating the GUI with modifications to handles. You may need this elsewhere, but for the job of updating properties of certain handle graphics objects, it is not really used.
One possibility is to create a timer to update the text fields on a regular basis. In your GUI's opening function, create a timer that defines an update function to run periodically:
T = timer('Period',1,'StartDelay',0.5,'TimerFcn', ...
{#updateTextBoxes,handles},'ExecutionMode','FixedRate');
start(T)
The update function would look like:
function updateTextBoxes(hTimerObj, timerEvent, handles)
global mystruct
% get mystruct data however you do it...
% maybe also get handles via handles=guidata(hTimerObj); instead of input
set( handles.textfield1, 'String', mystruct.value1 )
...
set( handles.textfieldN, 'String', mystruct.valueN )
EDIT: Do NOT forget to delete the timer (delete(T)) or stop it before you quit the GUI or do clear T, otherwise it will just keep running and you will have to quit MATLAB... No, I did not just do this myself!
You need to update the handles structure with this :
% Update handles structure
guidata(hObject, handles);
I created my first GUI using GUIDE in MATLAB.
The aim of the GUI is to execute a function with different arguments
The basic structure of the code is the following :
I have several arguments that the user will choose and then execute a function with all these arguments. The function called, named RSM is stored in the same folder as the GUI .fig and .m file
The GUI basic structure looks like this
different Listbox where the user can choose different values. Each listbox is one argument for my main function
A push button to execute the main function with the arguments
Each listbox is coded like this:
function popupmenu_contour_style_Callback(hObject, eventdata, handles)
contour_style=get(hObject,'Value');
handles.contour_style=contour_style;
guidata(hObject, handles);
then the main push button is coded like this:
function pushbutton2_Callback(hObject, eventdata, handles)
fitted_values = RSM_plot_function(...
handles.fullpathname,...
get(handles.checkbox_realspace,'Value'),...
get(handles.checkbox_reciprocalspace,'Value'),...
get(handles.popupmenu_plot_type,'Value'),...
get(handles.checkbox_color,'Value'),...
get(handles.checkbox_correctionforomega,'Value'),...
get(handles.checkbox_includeoriginline,'Value'),...
get(handles.popupmenu_contour_style,'Value'),...
get(handles.listbox_fitting,'Value'),...
get(handles.grid_density,'Value'),...
get(handles.contour_number,'Value')...
);
I used this technique to read the values of each listbox even if the user does not change them.
When I run the program for the first time it works perfectly. However, if I change the parameters of some listboxes I got a strange error:
Error while evaluating uicontrol Callback
Error using handle.handle/get
Invalid or deleted object.
Error in RSM>pushbutton2_Callback (line 227)
fitted_values = RSM_plot_function(...
I am not sure to understand the reason of this error. Neither am I sure that I used the correct method to get the values of the listboxes and pass them as arguments to my RSM function.
I am trying to build a program in MATLAB and I am using edit boxes but I want the value that the user will enter to be used later on from another function. So should I use the global variables or is there another way?
I tried to define the global variables outside the function but is not working.
I tried to define it inside the function and then call it from another function but it says that it is undefined. Is there a way that I can do that?
I am just using
function edit1_Callback(hObject, eventdata, handles)
str2double (get (hObject,'String'));
Thanks!! :)
If you want to store data within a Matlab-GUI, you can use the handles-structure like this:
handles.myVar=123;
%after this dont forget to save it (yes, this is a bit annoying):
guidata(hObject, handles);
later on, within another callback for example, you can find this data within the handles-struct:
handles.myVar
I created a GUI named SCADA and I added a boolean variable called StatusData which is a flag that that is set to false when the GUI is launched
handles.StatusData=false;
guidata(handles.output,handles);
I press a button and then a function is called which executes continuously (the function has infinite loop). After some time I press another button which sets the StatusData to true.
handles.StatusData=true;
guidata(handles.output,handles);
Now, I need to access the StatusData from the callback function (the same function I mentioned above), In order to acheieve this I sent the handle as a parameter when I called that function. Now, When the pressed the button that changes the StatusData, the data in the actual handle changes but I cannot access the updated StatusData as the function is already called.
How can I access the updated handle of GUI without sending it as a parameter.
Thanks
You can just pass in the hObject parameter to your function instead, and retrieve your value when it's needed using guidata; i.e.,
function some_callback(hObject, handles, ...)
myLoopingFunction(hObject, ...);
function myLoopingFunction(hObject, ...)
for someVar = something
% Update handles structure
handles = guidata(hObject);
end
Alternatively you could create a handle object and put that in the handles structure; e.g.,
% In a separate file:
classdef uiState < handle
% Probably should give this class a less general name...
properties
StatusData
end
end
% In your UI file:
function some_callback(hObject, handles, ...)
handles.state = uiState();
handles.state.StatusData = false;
% Now, when you modify handles.StatusData, the version used by
% myLoopingFunction will also be updated, because they point to
% the same object!
myLoopingFunction(handles.state);
function myLoopingFunction(state, ...)
for someVar = something
% Now you just have to check state.StatusData
end
For simple cases, I'd use the first method. For more complicated situations, where several parameters must be kept track of and they interact in complex ways, I would use the second. The second is also useful if you have a large chunk of data in some variable and want to stop it from being copied into every call to the UI.
Personally, for a complex UI I would usually create some application class that keeps track of the user interface (and provides a command-line interface to it) and make sure that was always available to my UI, but that is a bit like using a sledgehammer to open a jam jar in this simple case.