How to avoid using eval in this case?

2 visualizaciones (últimos 30 días)
xiaojuezi
xiaojuezi el 8 de Dic. de 2021
Comentada: Matt J el 8 de Dic. de 2021
Hi, I read in multiple threads that the usage of the function eval should be avoided as much as possible. But in the following case I couldn't find a neater way to do so. I have a uicontrol function, and I have several buttons that will set different variables in a similar way. The code is somewhat like below:
w = -1;
h = -1;
editW = uicontrol('Style','edit');
buttonW = uicontrol('Style','pushbutton');
editH = uicontrol('Style','edit');
buttonH = uicontrol('Style','pushbutton');
In total I have more than 5 pushbuttons, each set a specific variable to what is written in the associated edit field. One way to write the callback functions is:
buttonW.Callback = @setW;
buttonH.Callback = @setH;
function setW(hObject,eventData)
w = str2double(editW.String);
end
function setH(hObject,eventData)
h = str2double(editH.String);
end
In this way, I will have to write more than 5 callback functions, which they are simply doing very similar things, making the code look very redundant. So I was thinking using the eval function:
buttonW.Callback = {@setVariable,'w'};
buttonH.Callback = {@setVariable,'h'};
function setVariable(hObject,eventData,input)
% Grab the associated edit field
edit = eval(['edit',upper(input)]);
x = str2double(edit.String);
eval([input '= x']);
end
In this way, I only need to define the function once. Is there other way to somewhat achieve the same effect without using the eval function?
Thank you very much!
  2 comentarios
Walter Roberson
Walter Roberson el 8 de Dic. de 2021
function setW(hObject,eventData)
w = str2double(editW.String);
end
I am not clear as to what the purpose is of setting a local variable that is going to be immediately thrown away.
function SetVar(hObject, eventData)
value = str2double(hObject.String);
end
xiaojuezi
xiaojuezi el 8 de Dic. de 2021
Hi, the button is a "OK" button, when a user enters something in the edit field, the variable is only set when they press the button. The variables "w","h"......are also used in global scope. So if there are 6 variables, then there are 6 edit fields and 6 OK buttons, and each button should only control an associated edit field and variable.

Iniciar sesión para comentar.

Respuesta aceptada

Matt J
Matt J el 8 de Dic. de 2021
Editada: Matt J el 8 de Dic. de 2021
Store the numeric result to the UserData property of the button, instead of to individual variables.
edit(1) = uicontrol('Style','edit');
button(1) = uicontrol('Style','pushbutton');
edit(2)= uicontrol('Style','edit');
button(2) = uicontrol('Style','pushbutton');
input.edits=edit;
input.buttons=button;
[button.Callback]=deal({@setVariable,input})
function setVariable(hObject,eventData,input)
idx=arrayfun(@(a,b) isequal(a,b), hObject, input.buttons);
hObject.UserData = str2double(input.edits(idx).String);
end
  3 comentarios
xiaojuezi
xiaojuezi el 8 de Dic. de 2021
Thank you very much for your answer! I added this button function because users may be changing their input at any time, and the stored values might also be used at different places in the program. So I only want to change the stored values unless users have confirmed what they've entered.
Matt J
Matt J el 8 de Dic. de 2021
You’re welcome. Is the issue solved? If so, please click Accept.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Resizing and Reshaping Matrices en Help Center y File Exchange.

Productos


Versión

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by