why when i use two guides i'm losing the handles variables?

1 view (last 30 days)
function solicita_espacios(hObject, eventdata, handles)
if get(handles.checkbox1,'Value')==1% si el checkbox de materia gris es seleccionado
%en esta parte se pide al usuario que defina el espacio a trabajar de
%acuerdo a la cantidad que definió
%if (handles.Mgris)
Cespacios=str2double(get(handles.edit6,'String')); %cantidad de espacios nativo,normalizado etc.
for ce=1:Cespacios
opciones={'ninguno','espacio nativo','sin modular normalizado','modulado normalizado','nativo+sin modular normalizado','nativo+modulado normalizado','nativo+modulado+sin modular','modulado+sin modular normalizado'};
[s,v] = listdlg('PromptString','Seleccione un mapa:',...
'SelectionMode','single',...
'ListString',opciones)
switch (s)
case 1
espacio=[0 0 0];
case 2
espacio=[0 0 1];
case 3
espacio=[0 1 0];
case 4
espacio=[1 0 0];
case 5
espacio=[0 1 1];
case 6
espacio=[1 0 1];
case 7
espacio=[1 1 1];
case 8
espacio=[1 1 0];
end
EspacioMgris{1,ce}= espacio;
handles.EspacioMgris=EspacioMgris;
guidata(hObject, handles)
end
handles = guidata(hObject);
end
if get(handles.checkbox2,'Value')==1% si el checkbox de materia blanca es seleccionado
%en esta parte se pide al usuario que defina el espacio a trabajar de
%acuerdo a la cantidad que definió
Cespacios=str2double(get(handles.edit6,'String')); %cantidad de espacios nativo,normalizado etc.
for ce=1:Cespacios
opciones={'ninguno','espacio nativo','sin modular normalizado','modulado normalizado','nativo+sin modular normalizado','nativo+modulado normalizado','nativo+modulado+sin modular','modulado+sin modular normalizado'};
[s,v] = listdlg('PromptString','Seleccione un mapa:',...
'SelectionMode','single',...
'ListString',opciones)
switch (s)
case 1
espacio=[0 0 0];
case 2
espacio=[0 0 1];
case 3
espacio=[0 1 0];
case 4
espacio=[1 0 0];
case 5
espacio=[0 1 1];
case 6
espacio=[1 0 1];
case 7
espacio=[1 1 1];
case 8
espacio=[1 1 0];
end
EspacioMblanca{1,ce}= espacio;
handles.EspacioMblanca=EspacioMblanca;
guidata(hObject, handles)
end
handles = guidata(hObject);
end
if get(handles.checkbox3,'Value')==1 % si el checkbox de liquido cefalorraquideo es seleccionado
%en esta parte se pide al usuario que defina el espacio a trabajar de
%acuerdo a la cantidad que definió
Cespacios=str2double(get(handles.edit6,'String')); %cantidad de espacios nativo,normalizado etc.
for ce=1:Cespacios
opciones={'ninguno','espacio nativo','sin modular normalizado','modulado normalizado','nativo+sin modular normalizado','nativo+modulado normalizado','nativo+modulado+sin modular','modulado+sin modular normalizado'};
[s,v] = listdlg('PromptString','Seleccione un mapa:',...
'SelectionMode','single',...
'ListString',opciones)
switch (s)
case 1
espacio=[0 0 0];
case 2
espacio=[0 0 1];
case 3
espacio=[0 1 0];
case 4
espacio=[1 0 0];
case 5
espacio=[0 1 1];
case 6
espacio=[1 0 1];
case 7
espacio=[1 1 1];
case 8
espacio=[1 1 0];
end
EspacioLiquido{1,ce}= espacio;
handles.EspacioLiquido=EspacioLiquido;
end
handles = guidata(hObject);
end

Accepted Answer

Geoff Hayes
Geoff Hayes on 19 Oct 2014
You included a lot of code in your question. In the future, please just attach the m files to your question using the paperclip button. As well, please describe how you are using your two GUIs. Does one launch the other, do they both run at the same time, etc.
So you have two GUIs that "communicate" information between each other using global variables. (There are alternatives to this. You can store the data in the handles object of one GUI, and then access that handles data from the other. See how do you access one GUI from another for details.) You are then finding that the handles.EspacioMgris does not exist...but you don't say where this is failing, only that it isn't there when you enter the solicita_espacios function, which is called from the pushbutton1_Callback of your "bigger" GUI (not the menus one). Taking a look at this callback we see that your code
  • declares several global variables (that is fine, though you may want to explore the alternative already described)
  • sets a variable named x to be the handle of the edit3 control (suspicious...)
  • iterates over x, prompting the user for information
  • calls the function solicita_espacios (where you comment on the problem)
  • do some other stuff
  • again start iterating over x (??) and make use of handles.EspacioMgris in the inner loop (note that you set three global variables to the same handles.EspacioMgris{1,1} value)
  • does more stuff
So let us first look at the assignment of x
x=handles.edit3;
for vgauss=1:x
% etc.
This seems strange because the handle to a control/widget (in your case, the edit box named edit3) is (almost always) a positive non-integer, so of the form 179.34343321. So why would you want to iterate over this value? This doesn't seem correct (and isn't) but is explained in the callback to edit3
function edit3_Callback(hObject, eventdata, handles)
Val=get(hObject,'String');
NewVal = str2double(Val);
handles.edit3=NewVal;
guidata(hObject, handles);
So once the user has finished typing data into edit3, this callback fires and the code immediately grabs the string data from edit3, converts it to a number and then OVERWRITES the handle for edit3 with that number (saving it using guidata). This is WRONG. The handles structure manages all the handles (or unique identifiers) to all widgets/controls on your GUI, and all user-defined data (so these are the things that you add to it). The control identifiers (handles) are maintained in this structure so that your code can access the information stored in one control from the (say) callback of another. By overwriting this data, you are preventing other control callbacks from accessing this data. Note that in this callback, the value for hObject s the same as the value for handles.edit3.
You need to remove the edit3_Callback and all other similar callbacks for your other edit controls. Then, your code in the pushbutton1_Callback would change from
x=handles.edit3;
for vgauss=1:x
% etc.
to
x=str2double(get(handles.edit3,'String'));
for vgauss=1:x
% etc.
So we have really taken the body of your callback and re-used it here.
Now, if we look at the solicita_espacios function we see that it does
function solicita_espacios(hObject, eventdata, handles)
if (handles.Mgris)==1
Cespacios=handles.edit6;
for ce=1:Cespacios
opciones={'ninguno','espacio nativo',...};
[s,v] = listdlg('PromptString','Seleccione un mapa:',...
'SelectionMode','single',...
'ListString',opciones)
switch (s)
case 1
espacio=[0 0 0];
case 2
% etc.
end
EspacioMgris{1,ce}= espacio;
handles.EspacioMgris=EspacioMgris;
guidata(hObject, handles)
end
end
% then another if block
So it enters the if body if the condition (handles.Mgris)==1. As before, you don't see to save the results stored in your controls (in this case a checkbox) to other fields within handles. Just access this data directly as
if get(handles.checkbox1,'Value')==1
So once in the body, we again iterate over some value from edit6. The code
Cespacios=handles.edit6; %cantidad de espacios nativo,normalizado etc.
for ce=1:Cespacios
should be replaced with
Cespacios=str2double(get(handles.edit6,'String'));
for ce=1:Cespacios
and the callback for edit6 deleted.
Back to the code, the user is prompted with options for a number of times, and after each prompt the data is saved to the handles.EspacioMgris field, and guidata is called. Doing this repeatedly (on each iteration of the loop) is unnecessary, and so the two line
handles.EspacioMgris=EspacioMgris;
guidata(hObject, handles);
should be moved outside of the for loop, so that it just occurs the once.
Now that we've done the above for the grey (?) checkbox, the code does the same for a couple of other checkboxes.
Once we exit the solicita_espacios function, we are back in the pushbutton1_Callback and do start a couple of loops (again, fix the y=handles.edit4) and do
spaceWMG1=(handles.EspacioMgris{1,1});
spaceGMG1=(handles.EspacioMgris{1,1});
spaceLCG1=(handles.EspacioMgris{1,1});
Note that handles is a copy of the structure BEFORE the code entered the solicita_espacios function, so it won't have the updated data. You will need have either your solicita_espacios function return the handles structure as
handles = solicita_espacios(hObject, eventdata, handles);
and probably do the same for solicita_mapas, or just do
solicita_espacios(hObject, eventdata, handles);
handles = guidata(hObject);
I'm not sure if that really answers your question, but it does give you a couple of things to think about. Presumably you are initializing handles.EspacioMgris in your Opening_Fcn of the GUI to handle the case where the grey checkbox isn't checked.
  10 Comments
Geoff Hayes
Geoff Hayes on 23 Nov 2014
Steven - you should post this as a new question as it does not relate to the the original one.
That being said, look at how you are using exist
if(exist('handles.strSpaceMG')==1);
If you are checking to see if a field is a member of a structure, then you should use isfield as
if isfield(handles,'strSpaceMG')
Try the above and if you can't get it to work, then please post this as a separate question.

Sign in to comment.

More Answers (0)

Categories

Find more on Data Type Conversion in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!