Tải bản đầy đủ (.doc) (31 trang)

How do global variables differ from regular (local) variables? doc

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (460.45 KB, 31 trang )

How do global variables differ from regular (local)
variables?
Each function in MATLAB contains a set of variables specific to that function. Even in
the same .m file, you don’t have (direct) access to variables created in other functions
within the file. Global variables give you the ability to create/change a variable in one
function and have that updated variable accessible elsewhere. This post will discuss two
methods for handling (no pun intended) global variables, one of which is perfectly
integrated into Graphical User Interfaces (GUIs).
METHOD 1: global VARIABLE
The first (non-GUI) way to create a global variable is to use the function ‘global’. Create
the global variables X, Y, and Z with the command:
global X Y Z
The ‘global’ function needs to be called in each separate function (usually in the
beginning) where the variables will be called. Stylistically, the variable names are
usually longer names and all in CAPS to indicate global variables within the functions.
The documented example in the MATLAB helps shows this pretty well:
function tic
global TICTOC %define/incorporate global variable at start of function
TICTOC = clock;
function t = toc
global TICTOC %accesses variable TICTOC (or creates it if TICTOC is
undefined)
if nargout < 1
elapsed_time = etime(clock, TICTOC)
else
t = etime(clock, TICTOC);
end
Many hard-core coders prefer to avoid using ‘global’ except for constants. The reason
behind this is because it’s generally considered poor form to lock up a variable name (See
Steve L’s comment below for another reason!). While this won’t matter for smaller
programs and functions, when the files get to be many hundreds (or thousands or


millions) of lines long, it can be very difficult to keep track of all of the global variables
and to remember to call all the necessary variables at the start of each function. The great
thing about GUIs is that they already have a built-in global structure to deal with all of
your global variables: the handles. The handles structure is an input (and therefore
accessible) to every function in the GUI, making it perfectly capable doing everything the
‘global’ command can. In fact, you shouldn’t ever have to use ‘global’ command when
designing a GUI because the handles structure does the job so well. GUIs and ‘global’
don’t mix kids!
METHOD 2: handles.variable
As you may have seen from many of the blinkdagger GUI tutorials, the handles structure
is an extremely useful method to manipulate GUI boxes/buttons/tools. But the tool
data are all just stored variables that can be accessed anywhere within the GUI (aka
global variables!). Since we don’t need to edit any ‘property’ of the handles structure
(e.g. handles.static_text, ‘String’), we don’t need to use the ‘get’/’set’
commands. Creating the global variable is as easy as saying:
handles.x = 42;
%And of course, don't forget to update your handles structure:
guidata(hObject, handles);
handles.x is now an independent variable and note that it has no relation to the local
variable x.
x = 43;
is a completely valid command in the same function that would not overwrite your global
variable ‘handles.x’.
Remember, these variables can range from constants (e.g. 12) to strings (e.g. ‘Hello
World’) to structures, cells, and arrays of constants/strings.
Hopefully you can see the usefullness of global variables and will use them (properly!) in
your coding adventures.
11 Responses to “MATLAB - Global Variables”
1. on 30 Jun 2009 at 9:02 am 1Andrew Scott
When I started using GUIs a couple of years ago I couldn’t get this right, so ended

up storing all my global variables via setappdata(gcbf, ’string’, data). I’ve never
had a problem with this, although it is more cumbersome than the handles method
you describe here.
I think I’ll use your method in future.
2. on 30 Jun 2009 at 9:35 am 2 Steve L
Zane,
In the first method you said “Many hard-core coders prefer to avoid using ‘global’
except for constants. The reason behind this is because it’s generally considered
poor form to lock up a variable name.” That’s one reason to avoid using global
variables, but a much stronger reason to avoid using global variables is that it can
lead to bugs that are very difficult and time consuming to locate, particularly in
the context of a GUI.
Suppose I write a function that uses a global variable x.
function y = myglobalsquare
global x
if isempty(x)
x = 5;
end
y = x^2;
In isolation, this function works perfectly fine. I set the value of the global
variable x and then call myglobalsquare, and I get back the value x^2.
Now I incorporate this function into a GUI. I set it as the callback for one of my
GUI’s uicontrols and have another uicontrol’s callback set the value of the global
variable x.
I test it and it works, and I go on finishing up the GUI. But suddenly, when I
introduce a new object into the GUI and set up its callback, my “Square” button
no longer works! What’s going on? I haven’t made any changes to the Square
button in hours!
The problem, I find out after spending a LOT of time looking at myglobalsquare
and the callback that sets the global variable x, is that the callback for the new

object I introduced in the GUI _also_ uses the global variable x. Because of that
callback function’s manipulation of the global variable, the myglobalsquare
function no longer works the way I expect it to.
If you think of a function workspace as a house, with the input arguments coming
in the front door and the output arguments leaving by the back door, a global
variable is an open window that anyone can crawl through and move your
furniture around, potentially without you realizing it until you invite a very
important guest (the data for the real problem you’re trying to solve, not the data
you’ve used to test the function) for a visit.
On a side note, I suppose that would make a nested function an apartment in an
apartment complex, where the landlord has the right to come in and move stuff
around in certain circumstances [mainly maintenance or emergency situations]
and the resident doesn’t have the right to do certain things [like paint the walls.]
3. on 30 Jun 2009 at 10:22 am 3 Zane Montgomery
I love the analogy. Thanks for the tip Steve!
4. on 01 Jul 2009 at 6:43 am 4 MATLABDoug
ARGHH! Globals make me crazy…
The handles structure is not global. It is passed around to all the callbacks in a
GUI by default, but it is not global.
I know this is partially a religious issue, but I see way too many people abusing
true global variables because they do not understand scoping of variables and then
they end up in a real mess later.
Please do not use global variables unless you can explain to your teddy bear
( why
you really need them. My bet is you would be better off without them. See below
for alternatives.
On to my next religious issue: the handles structure is for handles. It just feels
untidy to put data in a structure specifically labeled for handles.
I see people putting just tons of data into the handles structure and it becomes a
real mess. Is it going to cause as many problems as globals? Not likely. However,

I highly recommend the use of GETAPPDATA and SETAPPDATA as shown in
this video:
/>To me, this is cleaner.
Loren is a fan of nested functions
/>scope/
Please consider the alternative before using unneeded globals. Globals are often
the cause of really tricky errors. Globals are just quicker, easier, more seductive.
Use nested functions or appdata, not as clumsy or random as a global. An elegant
weapon, for a more civilized age.
-Doug
 Anonymous
Is it ok to use the userdata from the root?
like
ud=get(0,’userdata’);
ud.x=42;
set(0,’userdata’,ud);
 on 02 Jul 2009 at 2:38 pm 6Anonymous
I’m writing GUIs that contain some pretty large data arrays, and don’t want these to be
unnecessary duplicated, using up RAM. I’m currently using global variables.
Whilst I appreciate the elegance of Method 2, would switching to this effectively double
my memory usage (with one copy of the data in the GUI’s handles structure, and the
other in the local handles copy)?
 on 01 Aug 2009 at 10:43 am 7Dey
Hi all
I apologize in advance because I don’t have a clue how start a new post…
I need a script which does the following.:
I have the following directory structures
C:/Big/ecm/sDDP/new/level1/level1_1/level1_1_1/*.ext
C:/Big/ecm/sDDP/new/level1/level1_1/level1_1_2/*.ext
C:/Big/ecm/sDDP/new/level1/level1_1/level1_1_3/*.ext

.
.
.
C:/Big/ecm/sDDP/new/level2/level2_1/level2_1_1/*.ext
C:/Big/ecm/sDDP/new/level2/level2_1/level2_1_2/*.ext
C:/Big/ecm/sDDP/new/level2/level2_1/level2_1_3/*.ext
.
.
.
etc.
I want to go through the folders levelx_y_z(where x, y, z stands for 1_1_1, 1_1_2 etc.)
to get the files *.ext. I don’t want to select these files manually with ‘uigetfile’, because
it’s
very time consuming. Could anyone help me please. I tried something with ‘fullfile(path,
‘*.ext’)’ but then I still have
to specify each path.
P.s. The folders levelx/levelx_y/level/x_y_z are named otherwise actually. I just wanted
to
illustrate the structure
 who can everyone help me!
i’m unstill about the gui ,i want to show the transfer function iin the Guide ,but how don’t
know begin
my following topic:
for G(S)=(7s^2+16s+10)/(s^4+5s^3+11s^2+16s+10)
and have to show :
+ time set
+ bulk acceleration
+error set
in the Guide
i hope you can make it help me

thank you
 on 23 Jan 2011 at 11:45 am 9Ameya
Having a Problem trying to plot an imported array,
the gui does not except a code from another .m file even though it’s shown in the
workspace…Kindly help
Dey
You can solve your problem in one line with a regular expression: regexp(text,
expression)
You can get the text input from dir and the expression below should match your files:
‘C:/Big/ecm/sDDP/new/level\d+/level\d+_\d+/level\d+_\d+_\d+/.*\.ext’
It may be a good idea to experiment a bit with regexp to get familiar with it since it can
be a bit tricky to get the expressions right.
MATLAB GUI Tutorial - UITABLE Part 2, How To
Access Table Data
Last time, we learned how to display data onto a table. This time, we’re going to learn
how to work with table data within a GUI framework. For example, say you wanted to
take the contents of the table manipulate the data. This tutorial will explain how to do
that, and much more.
Contents
• Accessing Table Data within GUI Callbacks
• Accessing only the Selected Data
• Next Time
• Links and Downloads
Accessing Table Data within GUI Callbacks
Let’s say you have the following GUI:
For simplicity sake, let’s assume that you would like to create a button that will add 3 to
each of the entries of the table when the button is pressed. How would you go about
doing this? It’s actually quite straightforward. Let’s take a look at the callback for the add
button:
function add_pushbutton_Callback(hObject, eventdata, handles)

% hObject handle to add_pushbutton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%get the table data
tableData = get(handles.uitable1,'data');
%add 3 to the table
tableData = tableData + 3;
%update the table
set(handles.uitable1,'data',tableData);
So now, when I press the “Add 3″ button, it adds 3 to the table! This is just a simple
example to show how to extract the data from the UITABLE, and to perform an operation
on it.
Accessing only the Selected Data
Now, let’s up the difficulty level a bit. Let’s say you selected a couple of cells that you
want to sum, as shown in the image below (You can hold onto the CTRL button while
clicking on individual cells to select multiple cells).
How would you go about doing this? Read on and all will be revealed.
Enabling CellSelectionCallback
The first thing we need to do is to enable the Cell Selection Callback. But first, why are
we doing this? Enabling this callback will allow us to keep track of what cells are
being selected on the table. You can do this by bringing up the Property Inspector for
the UITABLE, and then clicking the following icon as shown in the image below.
If you did it correctly, your m-file should have been updated to include the following:
% Executes when selected cell(s) is changed in uitable1.
function uitable1_CellSelectionCallback(hObject, eventdata, handles)
% hObject handle to uitable1 (see GCBO)
% eventdata structure with the following fields (see UITABLE)
% Indices: row and column indices of the cell(s) currently
selecteds
% handles structure with handles and user data (see GUIDATA)

In addition, the CellSelectionCallback field should now be populated as shown in the
image below:
Adding the Necessary Code
First, let’s create and initialize a variable to hold the table cell selection information. We
will call this handles.selectedCells, and initialize it in the opening function.
% Executes just before uitable_tutorial_02 is made visible.
function uitable_tutorial_02_OpeningFcn(hObject, eventdata, handles,
varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to uitable_tutorial_02 (see
VARARGIN)
%initialize this variable
handles.selectedCells = [];
Next, we go to the uitable1_CellSelectionCallback, which is the callback that we just
enabled.
% Executes when selected cell(s) is changed in uitable1.
function uitable1_CellSelectionCallback(hObject, eventdata, handles)
% hObject handle to uitable1 (see GCBO)
% eventdata structure with the following fields (see UITABLE)
% Indices: row and column indices of the cell(s) currently
selecteds
% handles structure with handles and user data (see GUIDATA)
%every time the cell selection changes, we update this data
%eventdata stores the indices of the selected cells
handles.selectedCells = eventdata.Indices;
%update the gui data
guidata(hObject, handles);

Adding the Selected Numbers Together
First, we’re going to add another button and a static text component to display the sum.
The modified GUI looks like this:
Now, we need to write the callback for the button we just added:
% Executes on button press in sumNumbers_pushbutton.
function sumNumbers_pushbutton_Callback(hObject, eventdata, handles)
% hObject handle to sumNumbers_pushbutton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%get the number of rows and columns
[rows,columns] = size(handles.selectedCells);
%get the data from the UITABLE
tableData = get(handles.uitable1,'data');
%initialize the sum
sum = 0;
%loop through each selected cell and keep a running sum
%can anyone thing of a better way to do this?
for x=1:rows
sum = sum +tableData(tableIndices(x,1),tableIndices(x,2));
end
%display the sum on the GUI
set(handles.sum_text,'String',num2str(sum))
And there you have it, now you can select any number of cells, and then sum up the value
of the contents!
Next Time
Next time, we’re going to talk about some of the cool features of the UITABLE that we
have not yet discussed, including different data types within the UITABLE.
Links and Downloads
Download Source Files
The MathWorks Documentation for UITABLE

Cool Things You can do with UITABLE
Doug’s Video on UITABLE
MATLAB GUI Tutorial - UITABLE Part 1, How to
Display Data
With the release of MATLAB 2008b, you are now able to add tables to a GUI. In the
past, there was no easy way to display your data in tabular form. With the UITABLE
component, displaying your data in tabular form is easy, and most importantly, looks
great!
Contents
• Adding a Table to Your GUI using GUIDE
• Displaying Data on the Table
• Adding Column and Row Labels
• Modifying your Table through the m-file
• Next Time
• Links and Downloads
Adding a Table to Your GUI using GUIDE
Within the GUIDE framework, you can add a table to your GUI using the following icon
from the toolbar: .
Here’s what the GUI will look like within GUIDE:
Displaying Data on the Table
We are going to populate the UITABLE component with data by pushing the “Populate
Table” button. Thus, we’re going to need to add some code to the pushbutton’s callback.
In the populate_pushbutton callback, we use the following code:
% Executes on button press in populate_pushbutton.
function populate_pushbutton_Callback(hObject, eventdata, handles)
% hObject handle to populate_pushbutton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%first, create a data matrix that has 5 columns, 4 rows
myData = rand(5,4);

%now populate the table with the above values
set(handles.uitable1,'data',myData );
Now, let’s run the GUI and push the button!
A neat feature is that the table is smart enough to fill out the table according to the size of
the data matrix that you feed it. So if I had done the following instead:
myData = rand(100,100);
The table would incorporate the use of scroll bars, as shown below.
Adding Column and Row Labels
A good way to spruce up your table is to add row and column labels. This helps
differentiate your data and makes it easy to identify. Within the GUIDE framework, we
can modify the labels by first bringing up the Property Inspector for the UITABLE. This
can be done by double clicking the UITABLE component.
Now, if you click on any of the fields in the above picture, it will bring up the Table
Property Editor. This is where you can add Row and Column labels. For example:
Make sure you click on the “Rows”, and that you select the “Show names entered below
as the row headers” option. Finally, you just need to modify the names. Similarly, you
can do the same for the columns.
Once you’re done with that. you should see the following:
And once you run your GUI, you can see the final result. A well labeled table that
displays your data beautifully!
Modifying your Table through the m-file
Sometimes it’s easier to work from within the m-file framework, rather than the GUIDE
framework. We could have done exactly what we did above programmatically through
the m-file. In the opening function we could have done the following:
%store the row headers into a cell array
rowHeaders = {'Blink','Dagger','Loves','MATLAB','!!!!!!'};
%set the row labels
set(handles.uitable1,'RowName',rowHeaders);
%do the same for the column headers
columnHeaders = {'Quan','Daniel','Rob','Zane'};

set(handles.uitable1,'ColumnName',columnHeaders);
In this example, we assumed that we knew the dimensions of our table. If you don’t know
the size of your table beforehand, then it can be difficult to apply data labels that are
meaningful. By working through the m-file, you obtain more flexibility since you won’t
have to go back and modify the .fig file every time you want to make a change. And if
you are going to apply dynamic labeling, then working from the m-file is going to be
much easier.
Next Time
Next time, we’re going to talk about how to work with manipulating the data within the
table.
Links and Downloads
Download Source Files
The MathWorks Documentation for UITABLE
Cool Things You can do with UITABLE
Doug’s Video on UITABLE
MATLAB GUI - Tool Tips are your Friends!
What is a Tool Tip?
A tool tip is supplementary information about a GUI component that appears when the
user hovers the mouse cursor over the GUI component. As you can imagine, this can be
quite useful for the user. See below for examples.
• Tool Tip for the add button:
• Tool tip for the first input parameter:
• Tool tip for the second input parameter:
How to Add Tool Tips
Within the GUIDE editor, you can add a tool tip by modifying the “TooltipString”
property using the Property Inspector. Simply double click on the component to bring up
the Property Inspector. The image below shows that the “TooltipString” property has
been modified for the Add! button.
Adding Tool Tips Programmatically
If you would rather add the tool tips within your code, you can use the SET command.

For instance, if you wanted to add a tool tip for the add button, you could do the
following in the opening function of the GUI:
%put this code into the opening function of the GUI

set(handles.input1_editText,'TooltipString','This is the first input.')
set(handles.input2_editText,'TooltipString','This is the second input.')
set(handles.add_pushbutton,'TooltipString','This is a tool tip! Press to
add.')
If you have a large list of tooltips, you may want to do it in separate m-file and call that
m-file in the opening function.
Download the Source Files and Other Links
Download the source files here.
Yair’s Undocumented Tips on How to Spice up Tooltips
Pimp My Gui Part 3: Help Me Help Yourself
Blinkdagger proudly presents Pimp My Gui, a series that will provide our readers with
tips and tricks on how they can make their GUIs beautiful on both the inside and outside.
In the previous post, we talked about using a custom menu bar to retain
functionality while clearing up space on a GUI. In this post, we’re going to
discuss how to implement a “help” feature for your GUI. The help feature
should be informative and simple so that any person can learn how to use the
GUI quickly. The help feature should offer other useful information such as the version
number, author, and other tidbits of information.
In the last post, we ended up with this GUI, but we never did anything for the “help”
portion of the GUI:
Contents
• How to use this GUI: Quick User Guide
• About this GUI
• Putting it all Together
• Addpath
• Next Time

How to use this GUI: Quick User Guide

×