Why does my method doesn't recognise the variable U that I defined as global?

94 views (last 30 days)
I wrote a method in the designer app, so that I can call the functions that I need without writting them every time for each button. But I get a little error while executing the third function ( in the for =1:numel(U)) line:
methods (Access = public)
function implement = loadingdata(app) % first function for loading data
load data.mat Table1
load data.mat Table2
.. end
function input = timeandfrequency(app) % 2nd function for the input windows
answer = questdlg('Is there a time stamp?',...
'Please give the time stamp',...
'yes','no','no');
if (answer == "yes")
prompt ={' type the start time in [HH:MM:SS] ','Type the endtime in [HH::MM:SS]'};
dlgtitle = 'Time in HH:MM:SS';
dims =[1 40];
definput = {'13:20:00','13:50:00'};
time_answer = inputdlg(prompt,dlgtitle,dims,definput);
st = time_answer{1,:};
et = time_answer{2,:};
end
answer = questdlg(' Which Frequency would you like to plot ?', ...
'', ...
'Frequency 1','Frequency 2','Frequency 3','Frequency 3');
end
function plotting = diagrams(app) % third function for plotting the data
for k = 1:numel(U)
Var = Variableunits.Variable;
Num = size(Var,1);
X = T.Variable==U(k);
Uhrzeit = round(seconds(T.Time(X)/1000)); %Umwandlung der Uhrzeit zum Format HH:MM:SS
Uhrzeit.Format='hh:mm:ss';
Uhrzeit = sort( Uhrzeit,'ascend');
Wert = T.Value(X);
if (answer == "yes") % Wenn ein Zeitstempel vorhanden ist
ind = find(Uhrzeit >= st & Uhrzeit <= et);%Die Uhrzeit zwischen Anfangsuhrzeit und Endzeit einschränken
Uhrzeit = Uhrzeit(ind);
Wert = Wert(ind);
end
switch answer
case 'Frequency 1'
....
case 'Frequency 2'
....
case 'Frequency 3'
....
end %switch
end %for
end %function
end %method
After executing the first button as an example, it calls the 3 function and then I get the error: Unrecognised function or variable U in the method, despite defining it as a global variable below:
% Button pushed function: Variable1Button
function H2_TEMPERATURE_Pt01CelsiusButtonPushed(app, event)
loadingdata(app) % first function
timeandfrequency(app)% second function
global Us
global U;
Us = ["Variable1"];
U = categorical(Us);
%for loop
diagrams(app) % third function
Why does the function cant recognise the variable U? How can the method recognises it from the button function?

Accepted Answer

Adam Danz
Adam Danz on 4 Dec 2020
Edited: Adam Danz on 4 Dec 2020
Don't use Global variables, especially in AppDesigner!
Instead, declare variables that are shared between app functions as private or public properties.
Private properties are for variables shared interally within the app. Public properties are for variables shared externally to the mlapp file.
See Matlab's documentation on app properties
Step 1: Declare the variable as a private|public property.
Add the property using the green "+" in the image below (in code view, within AppDesigner)
A private | public declaration will be automatically added to the code. Change the name of "Property" to the variable name.
It's also a good idea to give the variable a default value. I named the variable "myDescriptiveVariableName" and set it as NaN.
Step 2: Use the variable anywhere in the app
To use this variable, simply use app.myDescriptiveVariableName. Any function can update the value stored in that property.
For public variables accessed outside of the app, you just need the app handle and then you can access the variable in the same way as shown above.
Here are some reviews about how to get the app handle outside of the app
  6 Comments
Jason Brown
Jason Brown on 23 May 2023
This is straightforward and I've tried to implement it by loading a time series image in startupFcn and then send the image stack to properties for availability to other functions in the app. However, the image stack is emtpy coming from properties. Like this:
% Code that executes after component creation
function startupFcn(app)
% preload image frame number
app.FramemEditField.Value = 1;
app.FrameEditField_2.Value = 1;
app.FrameEditField.Value = 1;
% configure image axes
app.ImageAxes.Visible = 'on';
app.ImageAxes_2.Visible = 'on';
app.ImageAxes_3.Visible = 'on';
app.ImageAxes_5.Visible = 'on';
app.ImageAxes_7.Visible = 'on';
filterspec = {'*.det', '.det files'};
[f, p] = uigetfile(filterspec);
if (ischar(p))
fname = [p f];
[detfile_hg, detfile_lg, frametype, counter, trigger, frameindex] = ReadDet(fname, 4680, 200, 3, 1);
end
and then I add the outputs to properties, like this:
properties (Access = public)
% Description: store the .det file
detfile_hg;
detfile_lg;
frametype;
end
but when I call them from another function, something like a LoadImageButton_aoiPushed function using this call:
detfile = permute(app.detfile_hg, [2 1 3]);
the variable is empty. Where have I gone wrong?
Thanks in advance
Adam Danz
Adam Danz on 24 May 2023
You're not storing the value to the app properties. You're storing the to variables that have the same name as the app properties but those variables are cleared at the end of the function.
[detfile_hg, detfile_lg, frametype, counter, trigger, frameindex] = ReadDet
this should be
[app.detfile_hg, app.detfile_lg, app.frametype, counter, trigger, frameindex] = ReadDet(...)
Also, those properties are only defined when p is a char so think about setting default values when you declare the properties
properties (Access = public)
% Description: store the .det file
detfile_hg = 0; % for example...
...
end

Sign in to comment.

More Answers (1)

Théophane Dimier
Théophane Dimier on 4 Dec 2020
Edited: Théophane Dimier on 4 Dec 2020
you need to redeclare "global U" at the beginning your 3rd function, to create a variable "U" in that functions's workspace and to "synchronize" it with the other "U" variable
  1 Comment
Théophane Dimier
Théophane Dimier on 4 Dec 2020
but anyway, passing the variable U as an argument of the 3rd function would certainly be safer. As a general practice, global variable should be avoided as much as possible.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!