handles are getting deleted - matlab

I have 3 row-vectors, and would like to output them out of my GUI, if I close it.
First I tried it with global variables in the GUI, which i access and put them in the output function:
global horizontalFrames;
global verticalFrames;
global blackFrames;
varargout{1} = horizontalFrames;
varargout{2} = verticalFrames;
varargout{3} = blackFrames;
But, all values are ALREADY AT THIS POINT zero, even if i set them in the code.
Why are they set zero?
Then I tried it by the use of handles like this:
handles.horizontalFrames = horizontalFrames;
handles.verticalFrames = verticalFrames;
handles.blackFrames = blackFrames;
somewhere in the code (where the values are NOT all zero)
and then write this in the output function:
varargout{1} = handles.horizontalFrames
varargout{2} = handles.verticalFrames
varargout{3} = handles.blackFrames
the handles cant be found. It seems, like the handles are not accessible from the output function, or they are deleted. I'm desperate... where is my data, why can't I simply output it?

I found it out. I had to update my handles with
guidata(hObject, handles);
"somewhere in the code" again, means, immediately after adding my variables.
Greets, hope it helps someone.

Related

Variable persisting between function calls

Suppose I want to call a function twice, but I need the function to remember variables it initialized the first time it is called so execution can be changed in subsequent calls.
For example if I have a piece of code like this:
function random
if exist('a','var') == 0
fprintf('hello\n');
a = 1;
else
disp('goodbye\n');
end
end
How could I get MATLAB to remember that a equals 1 when when I call the code again? Specifically, I'm hoping to use this for a push button callback function in a program I'm writing.
MATLAB supports the keyword persistent, which you would use as follows:
function toggleval_persist
% Set up the persistent variable and initialize it.
persistent a;
if isempty(a)
a = 0;
end
if ( a == 0 )
disp('hello');
a = 1;
else
a = 0;
disp('goodbye');
end
end
Also, I wouldn't recommend using a persistent variable for toggling a button state. The button's state is usually available in the object structure for the GUI if you're using MATLAB's UI system.
What you could do (in the optics of using this code in a GUI) is set up a flag telling whether a has been initialized or not and pass it as an argument to the function random. Storing the flag (let's call it a_flag) in the handles structure of the GUI, for instance, would allow you to keep track of its value (actually stored in handles.a_flag) for example.
So in other words,you could set the flag to 0 during the creation of the GUI (or in its Opening_Fcn if you are using GUIDE) as follows:
handles.a_flag = false;
and then in the function called random, which you could call with: random(handles.a_flag):
function random(a_flag)
if ~a_flag
%// Update the flag
a_flag = true;
fprintf('hello\n');
a = 1;
else
fprintf('goodbye\n');
end
end
Even simpler would be to use global variables...but I like that idea better :)
EDIT
The point of my code is to demonstrate that we can use the handles structure of a GUI (as asked by the OP) to store the value of the flag. Since the structure is accessible from every callback pressing the pushbutton will update it the same way a persistent variable would.
Please try this code to see what I mean:
function TestGUI
clear
clc
hFigure = figure('Position',[200 200 200 150]);
handles.Disp_a_title = uicontrol('Style','text','String','a','Position',[20 100 60 20]);
handles.Disp_aflag = uicontrol('Style','text','String','0','Position',[100 100 60 20]);
handles.Button = uicontrol('Style','Push','Position',[50 50 60 20],'String','Update a','Callback',#(s,e) PushCb);
a = 0;
handles.a_flag = false;
guidata(hFigure,handles)
function PushCb(~,~)
handles = guidata(hFigure);
fprintf('Flag is %i\n',handles.a_flag)
if handles.a_flag == false;
disp('hello\n');
a = 1;
handles.a_flag = true;
else
disp('goodbye\n');
end
guidata(hFigure,handles)
end
end
Pressing the button twice results in the following output in the Command Window:
Flag is 0
hello\n
Flag is 1
goodbye\n
Which from what I understood is the expected behaviour the OP is looking for.

Growing a struct with GUI

I've been working on a little custom made database in MATLAB.
I have a GUI with a bunch of 'Edit Text' boxes and buttons.
The key is that I should be able to register an undefined number of students with some information like names, surnames, code etc. I've managed to store only one student (i.e the first time i push the 'Submit Button') but when i enter another student's information, MATLAB just overwrites the information from the previous registration.
Here's the Callback for the 'Submit' button
function Submit_Callback(hObject, eventdata, handles)
global n
n=n+1
% hObject handle to Submit (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
name1 = get(handles.name,'String'); %edit1 being Tag of ur edit box
name2=get(handles.name2,'String');
name3=get(handles.name3,'String');
major=get(handles.major,'String');
labavg=num2str(get(handles.labavg,'String'));
finalgrade=num2str(get(handles.finalgrade,'String'));
email=num2str(get(handles.email,'String'));
code=num2str(get(handles.code,'String'));
for ii=1:numel(n)
student_information(ii).name=name1
student_information(ii).surname1=name2
student_information(ii).surname2=name3
student_information(ii).code=code
student_information(ii).major=major
student_information(ii).final_grade=finalgrade
student_information(ii).laboratory_average=labavg
student_information(ii).email=email
end
assignin('base', 'student_information', student_information)
end
I've declared the counter 'n' as a global variable set to '0' in the workspace.
I'm not sure if my code isn't looping properly. Maybe the mistake is in there but I can't see how to fix it.
Can you please help me with my code?
Thanks!
I'm not sure what you were trying to achieve with your loop, but I don't see the need for it. Also, by using assignin, you are overriding the contents of student_information in your workspace. You are better off making student_information global in Submit_Callback in addition to n, then construct a new_student structure using your information and append it to student_information as follows:
name1 = get(handles.name,'String'); %edit1 being Tag of ur edit box
name2=get(handles.name2,'String');
name3=get(handles.name3,'String');
major=get(handles.major,'String');
labavg=num2str(get(handles.labavg,'String'));
finalgrade=num2str(get(handles.finalgrade,'String'));
email=num2str(get(handles.email,'String'));
code=num2str(get(handles.code,'String'));
new_student.name = name1;
new_student.surname1 = name2;
new_student.surname2 = name3;
new_student.major = major;
new_student.laboratory_average = labavg;
new_student.final_grade = finalgrade;
new_student.email = email;
new_student.code = code;
student_information(n) = new_student;
n = n + 1;
and that should append the new entry at the end of the struct array.

creating handles in a for loop

I'm creating a GUI with a large number of checkboxes
h.f = figure('units','pixels','position',[200,200,150,50],...
'toolbar','none','menu','none');
for i=1:100
num_data=round((100*(5*rand()))/100);
end
h.t(i) = uicontrol('style','text','units','pixels',...
'position',[30,820-15.*i,150,15],'string','za');
h.c.a(i) = uicontrol('style','checkbox','units','pixels',...
'position',[150,820-15.*i,125,15],'string','1');
if num_data>1
h.c.b(i) = uicontrol('style','checkbox','units','pixels',...
'position',[175,820-15.*i,25,15],'string','2');
end
if num_data>2
h.c.c(i) = uicontrol('style','checkbox','units','pixels',...
'position',[200,820-15.*i,25,15],'string','3');
end
if num_data>3
h.c.d(i) = uicontrol('style','checkbox','units','pixels',...
'position',[225,820-15.*i,25,15],'string','4');
end
if num_data>4
h.c.e(i) = uicontrol('style','checkbox','units','pixels',...
'position',[250,820-15.*i,25,15],'string','5');
end
h.p = uicontrol('style','pushbutton','units','pixels',...
'position',[40,5,70,20],'string','OK',...
'callback',#p_call);
% Pushbutton callback
function p_call(varargin)
vals=get(h.c, 'Value');
checked = find([vals{:}]);
if isempty(checked)
checked = 'none';
disp(checked)
else
for i=checked
Data1=dlmread(strcat(files{i}, ' PYRO.txt'),2,0);
plot(Data1(3:end,1),Data1(3:end,2))
hold on
end
end
hold off
The code is placing the checkboxes in the right place, but h is disappearing at the end of the for loop, and this is the error I'm getting.
??? Undefined variable "h" or class "h.c".
Error in ==> checkboxesGUI>p_call at 50
vals=get(h.c, 'Value');
??? Error while evaluating uicontrol Callback
How do I make it so I can call back on h?
The error indicates that p_call does not have access to the struct h where your handles are stored. Your entire code is not posted, but it seems clear that p_call is not nested in the function that owns h. Restructure your code so p_call has access to h, or pass h as an input argument every time it is called.
Also, a problem is that h.c is a struct, not a handle. Your handles are in the subfields of h.c (i.e. h.c.a, h.c.b, etc.). This is a bit messy, so I would suggest changing the code so you keep the checkbox handles in an array addressed via h.c(i) so your get and find lines will work.

Update Callback status in MATLAB GUI

I have developed a GUI interface in MATLAB. When I push a button search, I have seen the desirable result. However, when I change the textbox and push the search button again, it does not work and gives me following error:
Undefined function 'untitled2' for input arguments of type 'struct'.
Error in #(hObject,eventdata)untitled2('edit1_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating uicontrol Callback
Undefined function 'untitled2' for input arguments of type 'struct'.
Error in #(hObject,eventdata)untitled2('pushbutton16_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating uicontrol Callback
I must re-execute the all code! Is any way to repeatedly run the GUI?
As seen, when I change the Video ID to other number and push the search button, the results are not updated.
function pushbutton16_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton16 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%pathname='C:\Users\Dr Syed Abdul Rahman\Desktop\innovation final\video detail\';
string1 = get(handles.edit1,'UserData');
fName=strcat(cd,'\Video Detail\Video Detail',string1);
fid = fopen(fName);
if fid~=-1
s{1} = fgetl(fid);
s{2} = fgetl(fid);
s{3} = fgetl(fid);
s{4} = fgetl(fid);
s{5} = fgetl(fid);
s{6} = fgetl(fid);
s{7} = fgetl(fid);
set(handles.text4,'Visible','On');
set(handles.edit1,'Visible','On','String',s{1})
set(handles.edit2,'Visible','On','String',s{2})
set(handles.edit3,'Visible','On','String',s{3})
set(handles.edit4,'Visible','On','String',s{4})
set(handles.edit5,'Visible','On','String',s{5})
set(handles.edit6,'Visible','On','String',s{6})
set(handles.edit7,'Visible','On','String',s{7})
set(handles.axes4,'Visible','On');
cd './Images';
A = imread(s{1});
axes(handles.axes4)
imshow(A);
else
set(handles.text3,'Visible','On','String','File is not exist !')
end
Instead of this line "string1 = get(handles.edit1,'UserData');"
try this one
string1 = get(handles.edit1,'String');
There are a lot of weird things going on in pushbutton16_Callback:
You don't need to keep setting 'Visible','on' for all your editboxes
get 'String' like amir nemat said, not 'UserData'
Use fullfile instead of strcat
Don't forget fclose(fid)!
Don't do cd './Images' in a callback unless you cd back but even then it's not a good idea, just imread into that path.
Do imshow(A,'Parent',handles.axes4) instead of axes(handles.axes4); imshow(A);
Also, you might want to rename your GUI to something other than untitled2. ;)
As for why you are getting the error, I don't know for sure, but I suspect when gui_mainfcn tries to feval your untitled2.m to run the callback, it is running something else. Check for other untitled2 MATLAB-executable files: which -all untitled2.
You problem can come that you change your working folder when you use :
cd './Images';
A possible correction could be :
oldPath = cd('./Images'); % Return the path that you were before
A = imread(s{1});
axes(handles.axes4)
imshow(A);
cd(oldPath); % Go back in the folder with all your functions

wait for gui to finish

As already asked more or less in this question: https://stackoverflow.com/questions/14397729/working-with-multiple-guis-in-matlab
I want to have the output parameers and wait for a gui to finish.
I now use waitfor, but the output is always only a single handle
handle = uiConfigureCalibration('uiMain', handles.figure1);
waitfor(handle);
display(handle);
The output function of uiConfigureCalibration however passes several parameters:
function varargout = uiConfigureCalibration_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
if isfieldRecursive(handles, 'handles.files.calibration')
varargout{2} = handles.files.calibration;
varargout{3} = handles.calibration;
end
Any chance to get these parameters somehow in the calling function ?
You would have to do
[output,FilesCalibration,Calibration] = uiConfigureCalibration('uiMain', handles.figure1);
to grab additional outputs - you are only asking for one output in your function call, so you always get one output. However, this will fail if you output single parameter.
Since number of outputs is variable, I think it is better to return structure containing all outputs:
function output = uiConfigureCalibration_OutputFcn(hObject, eventdata, handles)
output.output = handles.output;
if isfieldRecursive(handles, 'handles.files.calibration')
output.files.calibration = handles.files.calibration;
output.calibration = handles.calibration;
end
Now function essentially returns a subset of handles structure, containing 1 or 3 fields depending on the structure of handles