When there are multiple GUIs in your MATLAB application, the need to let the GUIs communicate with each other is inevitable. While sharing data between the different callbacks within the same GUI may already turn some people off, the sharing of data among different GUIs is not as difficult as one may think.
In short, you need to write functions in the different GUIs to deal with establishing communication links and data exchange, and when the time comes to pull/push data to/from a GUI, simply call the appropriate functions via the GUI's functions to have the data updated.
When two GUIs are sharing data, one of them must be providing the data while the other must be receiving the data. For simplicity'sake, I am going to call the one that sends the data as the source gui and the one that receives the data as the target gui.
In the source gui, you need to have a function that returns the desired data when it is called, say, get_data(). Similarly, in the target gui, you need to have a function that read in (or use) the data, say, set_data().
Depending on where you initiate the data exchange between the two guis, the sequence of actions is different. If the communication is initiated at the source gui, you are pushing data to the target gui; on the other hand, if it is initiated at the target gui, you are pulling data from the source gui. The former case will call the set_data function in the target gui to have the data pushed over, while the latter case will call the get_data function in the source gui to have the data pulled from the source gui.
Getting down to the actual implementation, there are basically two steps. In the first step, you need to make the guis aware of each other's existence and know what their responsibility is; in the second step, you need to specify the detail/protocol of the communication. You can think of the first step as the laying down the necessary hardware and the second step as implementing software that utilize the hardware in place.
Step 1: Setting up the communication links between the guis
To share data between guis, they have to be aware of each other. In the simplest cases where you have a source gui and a target gui, you will need to have the handle of the target gui in the source gui, and the handle of the source gui in the target gui. To accomplish that, you can have a set_target function in the source gui and a set_source function in the target gui. When the functions are called, they will take the handle of the other gui and store it as an item in the handles structure for later use. Below is a sample set_target function in the source gui.
function set_target(source_handle, target_handle)
% retrieve handles structure in the source gui
handles = guidata(source_handle);
% assign target handle as an item in the handles structure
handles.target = target_handle;
% save the handles s
guidata(source_handle, handles);
With the set_target and set_source functions properly written in the source gui and target gui, running the following code will have the communication link established.
% This will be your main script
% start up the two guis
source_handle = source_gui;
target_handle = target_gui;
% establish the link between the two
source_gui('set_target', source_handle, target_handle);
target_gui('set_source', target_handle, source_handle);
Step 2: Setting up the communication protocol (well, in a way)
Once the links are established, you will need to implement rules as to what and how the data is shared. During the design, you need to make sure the guis make no assumption about what is going on in the other gui or what variables are being used. Knowing exactly what your intention is with each gui should be able to help you set up your rules properly.
As an example, I have two guis with text boxes and push buttons in them. The push button in the source gui is labelled 'Send', while the one in the target gui is labelled 'Retrieve'. The interaction is fairly straightforward, write whatever you can think of in the text boxes, once a push button is clicked, you will see the text in the source gui copied over to the text box in the target gui. That said, clicking the Send button will push the data, while clicking the Retrieve button will pull the data. Same results, different approach though. The set_data and get_data functions are posted below. Nothing fancy, they either set the string property or get the string from the text box.
function set_data(handles, s) % in the target gui
set(handles.txt_tgt,'string', s);
function s = get_data(handles) % in the source gui
s = get(handles.txt_src,'string');
Note that to be able to call these functions from a different guis, you need to first `publish' the functions by adding the handle to the function as an item in the handles structure. To do that, in the opening function of the gui (before the handles structure is saved), add
handles.set_data = @set_data;
to the target gui, and add
handles.get_data = @get_data;
to the source gui. Doing so will allow you to access these functions from a different gui.
As the final step, we just need to set up the callbacks of the push buttons, so that the data exchange will occur when the button is clicked. And it is in these functions, we will call the set_data and get_data function we prepared earlier.
% in the target gui
% --- Executes on button press in pb_retrieve.
function pb_retrieve_Callback(hObject, eventdata, handles)
% get the handle to the source gui
source_handle = handles.source;
% get the handles structure of the target gui
s_handles = guidata(source_handle);
% update string to the one returned by the get_data function
set(handles.txt_tgt, 'string', s_handles.get_data(s_handles));
% in the source gui
% --- Executes on button press in pb_send.
function pb_send_Callback(hObject, eventdata, handles)
% get the handle to the target gui
target_handle = handles.target;
% get the handles structure of the target gui
t_handles = guidata(target_handle);
% call the set_data function
t_handles.set_data(t_handles, get(handles.txt_src, 'string'));
Now, if you run the 'main' script to have the two guis running at the same time and have their link established, you will be able to observe the string passing from the source to the target.
The example can be downloaded here. Run the test_script.m file.
While the example used is a very simple two-gui with one-way data flow, the same concept can be expanded and applied to cases where you want one-to-many or many-to-many guis with two-way communications. As long as you can have a clear design before diving into the coding, things should be relatively straightforward.