Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
handles structure versus global variables

Subject: handles structure versus global variables

From: Todd Welti

Date: 30 Nov, 2011 18:22:09

Message: 1 of 5

I'm working on a large Guide-generated GUI project (5000 lines). In the past I have always used the handles structure to hold working data in addition to object handles. It has worked pretty well in the past. In this project, it has gotten complicated, with some callbacks calling other callbacks, and also a second guide-created GUI figure called by the main GUI figure and interactions between the two. An insideous problem I keep running into is that one callback function calls another callback function, passing handles to it. Function 2 modifies handles structure and saves it (guidata(hObject, handles)). But when function 2 returns to function 1, and function 1 at some later point saves handles again (guidata(hObject, handles)), it saves the LOCAL version of handles, thus overwriting the changes made by function 2. That, and related errors are causing me to spend much time on the
code.

Possible solutions are:
1. Use "handles = guidata(hObject)" in function 1 right after calling funciton 2 to update handles in the local scope. Works if you always remember to do it. handles is then essentially equivalent to a global variable, but with more lines of code needed, right?

2. Pass handles into and out of the callback funciton being called direclty. Like:

Callback_function1()
  ...
  ...
  handles = Callback_function2(hObject, handles)
  ...
  ...

this would work, but if guidata(hObject, handles) is used in function 2 anywhere, those changes would be lost in function 1 (basically the same problem I already outlined).

Is there a question in any of this? Yes, my question is whether or not it might be simpler to just use a global variable in certain cases (things like timer handles, status flags, etc. which may legitimately need to be accessed by several different functions). I don't have to worry about scope with the global variable, what you see is what you get. I write it all in caps so it is recongnizable as such, and only would use them sparingly. I have switched to global variables (only 2) int he current project and things are running much better.

I know global variables are discouraged in general. Since I'm not the greatest programmer, perhaps I'm missing something. I would like to know if I am really barking up the wrong tree here...

Subject: handles structure versus global variables

From: Jonathan

Date: 2 Dec, 2011 15:12:07

Message: 2 of 5

"Todd Welti" <twelti@harman.com> wrote in message <jb5s8h$9i5$1@newscl01ah.mathworks.com>...
> I'm working on a large Guide-generated GUI project (5000 lines). In the past I have always used the handles structure to hold working data in addition to object handles. It has worked pretty well in the past. In this project, it has gotten complicated, with some callbacks calling other callbacks, and also a second guide-created GUI figure called by the main GUI figure and interactions between the two. An insideous problem I keep running into is that one callback function calls another callback function, passing handles to it. Function 2 modifies handles structure and saves it (guidata(hObject, handles)). But when function 2 returns to function 1, and function 1 at some later point saves handles again (guidata(hObject, handles)), it saves the LOCAL version of handles, thus overwriting the changes made by function 2. That, and related errors are causing me to spend much time on
the
> code.
>
> Possible solutions are:
> 1. Use "handles = guidata(hObject)" in function 1 right after calling funciton 2 to update handles in the local scope. Works if you always remember to do it. handles is then essentially equivalent to a global variable, but with more lines of code needed, right?
>
> 2. Pass handles into and out of the callback funciton being called direclty. Like:
>
> Callback_function1()
> ...
> ...
> handles = Callback_function2(hObject, handles)
> ...
> ...
>
> this would work, but if guidata(hObject, handles) is used in function 2 anywhere, those changes would be lost in function 1 (basically the same problem I already outlined).
>
> Is there a question in any of this? Yes, my question is whether or not it might be simpler to just use a global variable in certain cases (things like timer handles, status flags, etc. which may legitimately need to be accessed by several different functions). I don't have to worry about scope with the global variable, what you see is what you get. I write it all in caps so it is recongnizable as such, and only would use them sparingly. I have switched to global variables (only 2) int he current project and things are running much better.
>
> I know global variables are discouraged in general. Since I'm not the greatest programmer, perhaps I'm missing something. I would like to know if I am really barking up the wrong tree here...

I think that you really just have to be careful and determine which callback functions actually modify your guidata. If a function modifies the guidata in any way, then rewrite it at the end of that function. Due to the fact that matlab can't execute two callbacks simultaneously, you won't have any issue of one callback modifying the data while another callback is executing.

Also, I've found it beneficial that if I call Callback2 from Callback1, that in addition to saving the guidata at the end of Callback2, I actually return the guidata as well so that it is accessible to Callback1 without having to re-retrieve the guidata.

I would recommend against global variables, especially with GUIs because that prevents you from running two copies of the program simultaneously.

Subject: handles structure versus global variables

From: Todd Welti

Date: 7 Dec, 2011 00:27:09

Message: 3 of 5

"Jonathan" wrote in message <jbaps7$lfs$1@newscl01ah.mathworks.com>...
>
> I think that you really just have to be careful and determine which callback functions actually modify your guidata. If a function modifies the guidata in any way, then rewrite it at the end of that function. Due to the fact that matlab can't execute two callbacks simultaneously, you won't have any issue of one callback modifying the data while another callback is executing.
>
> Also, I've found it beneficial that if I call Callback2 from Callback1, that in addition to saving the guidata at the end of Callback2, I actually return the guidata as well so that it is accessible to Callback1 without having to re-retrieve the guidata.
>
> I would recommend against global variables, especially with GUIs because that prevents you from running two copies of the program simultaneously.

It's not a matter of multithreading, it's a conflict between a saved verison of handles, and the local scope version. So, you are suggesting saving handles using guidata AND passing and returning the variable?

Subject: handles structure versus global variables

From: Jonathan

Date: 7 Dec, 2011 01:20:10

Message: 4 of 5

> It's not a matter of multithreading, it's a conflict between a saved verison of handles, and the local scope version. So, you are suggesting saving handles using guidata AND passing and returning the variable?

What I am suggesting is that if you plan on having a callback be called from another, you must either save the guidata right before callig it, then retrieve it immediately afterwards, or you can use varargout on your callbacks and always return the guidata which may or may not be used. Below is an example.

function main()
    figure()
    uicontrol('units','norm','pos',[0 0 0.5 0.5],'string','btn1','callback',@button1callback);
    uicontrol('units','norm','pos',[0.5 0 0.5 0.5],'string','btn2','callback',@button2callback);
    uicontrol('units','norm','pos',[0 0.5 1 0.5],'string','Reset','callback',@resetData)
end


function resetData(varargin)
    
    disp('INSIDE RESET CALLBACK')

    data = struct('button1premodification',false,...
                  'button1postmodification',false,...
                  'button2modified',false);

    guidata(gcbf,data)

    disp(data)
end

function button1callback(varargin)
    data = guidata(gcbf);

    % Make a modification
    data.button1premodification = true;

    disp('BEFORE CALLING BUTTON2CALLBACK')
    disp(data)

    % Simulate button 2 press
    data = button2callback(varargin{:},data);

    % Now make another change
    data.button1postmodification = true;

    disp('AFTER CALLING BUTTON2CALLBACK');
    disp(data)

    % Now save this data
    guidata(gcbf,data);

end

function varargout = button2callback(handle,eventData,data)
    if ~exist('data','var')
        data = guidata(gcbf);
    end

    data.button2modified = true;

    disp('INSIDE BUTTON2CALLBACK')
    disp(data)

    guidata(gcbf,data);

    varargout{1} = data;
end

Subject: handles structure versus global variables

From: Todd Welti

Date: 8 Dec, 2011 18:14:08

Message: 5 of 5



I guess my basic uneasyness is about mixing methods for handling the data (storing in figure app data or just passing the data in and out of the other functions). It seems if you are going to pass the data in and out, you should just do that and not save it anywhere else (giving you the most control). OR, save it in the figure app data using guidata and NOT also pass the variable. In that case I wonder if it would be a good idea to keep the data in a separate structure (not handles structure) and make a general use function for calling other funcitons in a guide GUI, that would just save the data, call the function, and then save the data again and return. That way you would never forget to save before and after.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us