In Matlab, how to call GUI callback functions without the GUI? - matlab

I am not a GUI programmer, as will become obvious. If anything, I'm trying to unmake a GUI. I am using a program called art (found here, if it's useful to see) that generates figures and variables that I would like to save. You can call art from a batch script and make it read a config file for its inputs, which is what I'm doing, but you have to manually generate and save much of its output (variables and figures) in the GUI. I'd love to automate this process, but I am really struggling.
I think the core of my issue would be solved if I knew how to force the callback functions to be called. For instance, there is a function in art showCorr_Callback(hObject, eventdata, handles) (which is governed by a radio button in the GUI). It has a test condition to execute:
if (get(handles.showCorr,'Value') == get(handles.showCorr,'Max'))
I've tried inserting
mx = get(handles.showCorr,'Max'))
setappdata(handles.showCorr,'Value', mx)
into a function I know executes, the opening function, function art_OpeningFcn(hObject, eventdata, handles, varargin). That doesn't seem to have any effect. If I knew how to make the callback functions execute, perhaps I could insert the code that saves the figure into the functions. Somewhere in Matlab's GUI scripts there must be something that is continually testing for a change in state in the GUI. Where is that thing? How can I fool it into thinking a radio button has been pressed?
Thanks for your help, and please let me know if I need to provide more information.

First of all, if you want to set the Value of handles.showCorr, you won't use setappdata as that just stores arbitrary data (by key/value pair) into the graphics object. You actually want to set the Value property.
set(handles.showCorr, 'Value', get(handles.showCorr, 'Max'))
This should trigger any callbacks that are assigned to handles.showCorr.
If, for some reason this doesn't trigger the callback, you can always trigger it manually. If you already know the callback, you can call it explicitly.
showCorr_Callback(hObject, eventdata, handles);

Related

Check if editbox is active (and evaluate WindowKeyPressFcn only if its not) in matlab

I would like to be able to test whether given edit box (uicontrol with 'style' set to 'edit') is being used at the moment (whether the cursor is inside that box / the edit box has focus).
Unfortunatelly the 'Selected' property of the editbox seems to be 'off' all the time and it's use is discouraged by MathWorks
I am open to Java solutions (but I have not tried any yet).
Background
My broader goal is to activate specific functions in response to keys pressed by the user (keyboard shortcuts) but only if the user is not typing these letters into an edit box.
I evaluate keyboard shortcuts with 'WindowKeyPressFcn' callback. I thought about using editbox's 'KeyPressFcn' callback to block 'WindowKeyPressFcn' (by passing something through setappdata or 'UserData') but it seems that 'WindowKeyPressFcn' is always evaluated first.
So now I'm trying to detect whether the editbox is in use some other way.
Since MATLAB uicontrols have underlying Java Swing GUI controls, I can think of two "Java solutions":
Associate a FocusGainedCallback with the Java object of editbox (using FindJObj - see below) (and possibly other UI elements), and update some handle \ persistent \ global variable from this function to hold the currently focused object handle. This type of callback is mentioned in an UndocumentMatlab article on uicontrol callbacks.
You should be able to use Java'sisFocusOwner() method on the underlying java object of your editbox (this method is mentioned in the Java documentation of the focus subsystem).
Note: the simplest way to get the java object is using the utility FindJObj that is briefly described here.
An alternative, much simpler method, would be to use the WindowKeyReleaseFcn callback of the GUI figure. This gets fired after the release of the keystroke, hence it gets executed after the gco gets the updated value of the currently focused uicontrol. The following check in the beginning of the WindowKeyReleaseFcn can determine if the keystroke comes from the edit box:
function figure1_WindowKeyReleaseFcn(hObject, eventdata, handles)
% gco is already updated by the time we are here to reflect the uicontrol
% which is in focus
if isequal(gco, handles.hEditBox) % Keystroke comes from the edit box
return
end
% Keystroke does not come from the edit box -- Do something here...

How do I execute a function that receives handles as an argument, in another GUI?

I'm trying to change my plot in my main GUI according to a different number of options that I've put in another GUI. So, the main objective of this is to press the "OK" button on my second GUI, and that automatically changes the plot of the main one. I've already defined a function that does all that in my main GUI, and I wanted to use it on my second one.
Basically, I'm trying to use a function from one GUI to another and that function receives handles as its only argument.
Here's a bit of what I want
Main GUI - plotGraphs(handles) - This is the function in my main GUI that plots a graphic, according to several defined global variables.
Second GUI - Changes some of those global variables. Pressing "OK", the function plotGraphs is called and should change the Main GUI, according to the new variables.
I just don't know how to do this. I've tried putting this into the "OK" button callback
plotGraphs(handles)
close(secondGUI);
And it does not work. I've also tried passing the handles from the Main GUI to the second, but that does not seem to work either, or maybe I'm doing something wrong. Also, I'm using GUIDE for my GUI.

GUIDE in MATLAB

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

Reading GUI Data from a Matlab Script File

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.

Avoid interruption of callback functions in Matlab GUI

I have a Matlab GUI that needs a high time to execute some callback functions. Besides, these functions include the following code:
drawnow('expose');
pause(handles.data.delay);
I want to avoid that those callback executions get interrupted in order to avoid data inconsistency if the user presses other buttons. Thus, I modify the figure settings as:
set(handles.figure, 'BusyAction','cancel', 'Interruptible','off');
However, the callbacks are still interrupted. How can I avoid it?
Note: I think that the problem is that I need to propagate the 'BusyAction' and 'Interruptible' values to all the controls in my GUI, is there any way to do it automatically? Like, for example, modifying the default value before generating the GUI.
The fastest and cleanest way to propagate any property to all UI objects is with findobj:
set(findobj('Type','uicontrol'), 'BusyAction','cancel', 'Interruptible','off');