INTERACTING TWO MATLAB GUIS PROGRAMATICALLY

A good knowledge in developing GUI by using MATLAB GUIDE is required. For those who do not have any, this site is a good place to start. If it is offline, there are tons out there, find one.
Acknowledgement: this example is based on Doug Hull’s work. While he use GUIDE for building this example, I approach it programmatically.

1.     Develop GUI

On command window, type:
guide
a new window will appear, see (figure 1).
Click menu ‘Tools’ à GUI Options. A Popup window will appear (figure 2). Click ‘Generate FIG-file only’. Click ‘OK’ to close the window. Add and arrange several uicontrols to the plane so that it will look like figure 3. Save the GUI to ‘appDataTest1’ or whatever one likes.

Now, open MATLAB editor, save the file to the same name as the GUI one just built. Actually one can save the mfile to any name, but it is a good practice, though. One will know later why.

First step, call the GUI one just built, by calling the GUI’s name.
fig1 = openfig('appDataTest1.fig');

read more... 




for cleanliness reason, it’s good to clear the command window and delete previous variables created by adding this line before calling the GUI
                clc, clear all

Then, save the handle of current figure. Be careful while calling it, make sure one remember the variable’s name.
                fh1 = guihandles(fig1);

The figure one just called will be displaying default value. In other words, it is plain as it was first designed (see figure 4). Let’s add some touches. Add this line to change the GUI’s name and set GUI’s toolbar to none.
set(fig1,'name','GUI 1',...
    'toolbar','none');

These lines will change the texts on the GUI.
set(fh1.text1,'string','1st GUI','fontsize',16);
set(fh1.text2,'string','Image without treshold');
set(fh1.text3,'string','Image with threshold');

Then, we assign function into the ‘pushbutton’-s and give them names.
set(fh1.pushbutton1,'string','Load Image',...
    'callback',@loadImage);
set(fh1.pushbutton2,'string','Threshold',...
    'callback',@threshold);
set(fh1.pushbutton3,'string','Quit',...
    'callback',@closeall);

Now, the GUI will look like figure 5. We will use one of the way to make GUIs interact to each other, that is ‘Application Data’. One can read more about this feature from MATLAB help by typing this in command window.
docsearch application data

2.     Application Data

Application data add user-defined variables into the GUI application the user has just built. The steps are:
1.       Attach the GUI into the main handle of the application; in this case it will be the root.
2.       Then attach any number of variables one like to the GUI that has just been attached. This is one of the advantages of ‘Application Data’ over other methods.
3.       The variables can be standard type of variables, such as the name of pushbutton or function’s name. We’ll learn this later.
4.       Once we have our variables attached to the root, other GUI can call that variables, process them and return them back to the main GUI.
Let’s see how this works. In this example, right after the codes we added just now, add these lines.
setappdata(0   , 'hMainGui'            , fig1);
setappdata(fig1, 'appDataThreshValue'  , 121);
setappdata(fig1, 'appDataUpdateImage'  , @updateImage);

The main handle of the application is root, which referred by ‘0’ here. To refresh our work, fig1 is the handle of our GUI. To this handle we attach variables for threshold value and a function called ‘updateImage’. The name of the appdata associated with these variables must consistent through all our code.

Now, the setup for our application data has completed, it’s time to code the function we just associated with our pushbuttons.
function loadImage(varargin)
    % get the value of hMainGui defined previously.
    h1 = getappdata(0, 'hMainGui');
    [fileName, path] = uigetfile('*.jpg','Select a jpg file');
    % store fileName in an appData
    setappdata(h1, 'appDataImageFilename', fileName);
    updateImage;
end

The codes above call the appdata attached to the root and store it into h1. one can later check that the value for h1 and fig1 are the same. In this function, we call another function named ‘updateImage’. The codes for this function is below
function updateImage(varargin)
    h2        = getappdata(0 , 'hMainGui');
    fileName  = getappdata(h2, 'appDataImageFilename');
    threshval = getappdata(h2, 'appDataThreshValue');
   
    try
        I = imread(fileName);
        II = (I > threshval);
        imshow(I , 'parent',fh1.axes1);
        imshow(II, 'parent',fh1.axes2);
    catch e
        errordlg(e.message,'Error Detected','modal');
    end
end

As one noticed, within this function we also load the root’s appdata. We also load the variables we stored before. The function imread read the file and imshow displays the file to the GUI. Type help imread or help imshow for more information regarding these functions.
To complete the code for this first GUI, add these codes
function threshold(varargin)
    appDataTest2;
end
function closeall(varargin)   
    close(gcf);
end
end

The function threshold calls the second GUI and closeall closes the GUI. Now, we can try running the mfile by pressing F5 or click the button. Click the ‘Load Image’ button, a popup will appear where we must select a jpg file, see figure 6. The selected image[1] will be displayed in the GUI’s two axes (figure 7).
For the second GUI’s development, refer to figure 8. The code for the second GUI is listed below.
function appDataTest2
fig2 = openfig('appDataTest2.fig');
fh2 = guihandles(fig2);
set(fig2,'name','GUI 2');
set(fh2.text1,'string','2nd GUI','fontsize',16);
set(fh2.pushbutton1,'string','Close','callback','close(gcf)');
set(fh2.slider1, 'max', 255);
set(fh2.slider1, 'min', 0);
set(fh2.slider1, 'callback', @callback);
handlegui2 = getappdata(0 , 'hMainGui');
threshval  = getappdata(handlegui2,'appDataThreshValue');
set(fh2.slider1, 'value', threshval);
    function callback(varargin)
        evalUpdateImage = getappdata(handlegui2, 'appDataUpdateImage');
        thresh = get(fh2.slider1,'Value');
        setappdata(handlegui2, 'appDataThreshValue', thresh);
        feval(evalUpdateImage);
    end
end

Explanation: to interact with the first GUI’s variables, in the second GUI’s mfile we need to load the root’s appdata by invoking
handlegui2 = getappdata(0 , 'hMainGui');.
This way, all variables attached to it will also available for current GUI. There is only one callback for this GUI, that is the slider’s callback. This is where we call the function we attached to the root earlier. From the value retrieved from slider, we transfer it back to the root’s appdata using
setappdata(handlegui2, 'appDataThreshValue', thresh);
we then ‘evaluate’ the function by calling
                feval(evalUpdateImage);
Figure 1 GUIDE window

Figure 2 GUI Options

Figure 3 Completed first GUI

Figure 4 The Called figure


Figure 5 GUI after some touches


Figure 6 Select a jpg file

Figure 7 The selected image is loaded

Figure 8 Second GUI
That’s it. Try playing around with it. One can remove the semicolons (;) to see the actual value in command window. Email me your comment to abqorian@gmail.com.

3.     Reference

[1] http://www.blinkdagger.com
[2] http://www.mathworks.de/matlabcentral/fileexchange/authors/4987


[1] The image is the same file provided in the zip package from Doug’s blog.

0 Comments »

Leave a comment

Disclaimer !

This site and its contents are copyrighted to Abqori Aula unless otherwise mentioned. The images, videos, and other artworks are belong to their authors. This site does not host any copyrighted files.