Is it possible to "bind" the value of a uieditfield to a variable?

7 visualizaciones (últimos 30 días)
Paul
Paul el 21 de Dic. de 2022
Comentada: Paul el 29 de Dic. de 2022
In the language I am most familiar with (Visual Foxpro) it is possible to have a textbox with a ControlSource property set to a variable (e.g. MyVar). The textbox displays the value of myVar. Changing the value in the textbox changes the value of MyVar, and vice versa.
Is it possible to do something similar with a uieditfield? If not, I will have to manually set the value of the uieditfield whenever the value of my variable changes.
Might it be possible for the uieditfield to take its value from a function and be dynamically updated in that way? Any other suggestions?
Thank you.
  3 comentarios
Paul
Paul el 23 de Dic. de 2022
Thank you Stephen. I wil comment fully in the next few minutes.
Paul
Paul el 23 de Dic. de 2022
This is in part prompted ny Stephen's contribution but will I hope clarify things for everybody.
I am plotting two graphs of pH values against volume of base for two different acids. The values to be plotted are dependent on four different variables for each acid. There are a total of 6 uieditfields (and two dropdowns) for the user to enter the different parameters. So before the calculation can take place, the values in the uieditfields must be assigned to the variables (it would be too ugly and cumbersome to use the uieditfield values directly, especially since the calculations require the use of fsolve).
I was originally intending to carry out the calculations (and plotting) when the user clicked on a "Do it" button. I then decided it would be nice to recalculate and plot after any changes to the parameters in the uieditfields. I therefore decided to make use of ValueChangedFcn. An example is here:
efCa1 = uieditfield(gl,'numeric','Value',Ca1,'ValueChangedFcn',@(efCa1,event) valueChange(efCa1,"Ca1"));
The same valueChange function is used for each of the controls. The first parameter (in this case efCa1) tells valueChange which control was changed and the second parameter (in this case "Ca1") tells valueChange which variable efCa1 is associated with.
valueChange sets the value of the variable (Ca1) to the value of the uieditfield (efCa1.Value) and then calls a function (makePlot) which performs the calculations and plots the results. This is now working very nicely.
My apologies for staing earlier "I will have to manually set the value of the uieditfield whenever the value of my variable changes". That was totally misleading.
My thanks to everybody for their contributions. My only problem now is in deciding which answer to accept!

Iniciar sesión para comentar.

Respuesta aceptada

Rik
Rik el 21 de Dic. de 2022
Editada: Rik el 22 de Dic. de 2022
I think the easiest way to do something like this would be to make your variable a class with a value and a handle. If you create a set function in that class you can use it to set the String property of the handle object.
Edit:
I have attached an example implementation that only really needs good documentation and input validation. It hides the internal structure by overloading disp.
h=text(0.5,0.5,'txt');
A=BoundVariable(0,h);
A.value=2; % as you can see, it even works for text objects
  24 comentarios
Walter Roberson
Walter Roberson el 28 de Dic. de 2022
We could imagine that Mathworks could potentially have implemented something along the lines of
A = 42;
linkVariable(A, app.UIedit7.Value)
such that A remains a numeric variable that can be used in calculations like sind(A*2) and that plain assignment to A
A = 30;
affected the output of the edit field and that changing the edit field changed the current value of A (assuming that it exists in a live workspace or as a persistent variable.) That would, after all, be similar to what debuggers can do, with the variable browser giving a "live" view to a variable.
We can imagine that they could have done that, but it is not technically possible at the MATLAB level at this time, as assigning to an unindexed variable currently breaks any existing links except that persistent and global variables stay accessible by name. We know that internal debugging facilities must exist but we do not appear to have any way to access the facilities.
We could imagine creating a new class that derived from double and so could be used in arithmetic, but might perhaps not pass isa('double'). And we could imagine tying it to a control such that certain kinds of value changes got reflected in the control. Not full assignment to the entire variable, but indexed assignments perhaps, A(1)=30 or a set() method, something like that. Could making a change to the control alter the variable? Well the variable would not generally be in scope of the control, not unless your creation routine did something like evalin('caller', 'global NAME'). Maybe you could hack something along those lines, but normally value classes are not "remotely" accessible and changing all references could get messy. Unless, that is, you make the class a handle class.
But is it possible to derive both from double() and handle() such that changes in the control propagate immediately, but arithmetic routines can still transparently use the value? I don't know for sure, but I rather suspect not.
So that gets us to the remaining possibility, of creating a class that provides a "friendly" interface to talk about the value of a control but requires special functions to assign to or get the value and which cannot be used transparently in arithmetic statements.
In this last case, the linked variable becomes similar to an alias.
A = BoundVariable2(app.CONTROL)
A.value %to get at value for arithmetic taking into account changes to the control
A.value = 30 %to set the value including changing the control
standing in for
app.CONTROL.value
app.CONTROL.value = 30
is it worth it? I have my doubts.
Paul
Paul el 29 de Dic. de 2022
I had no idea when I posted this question that it would prompt such lengthy and interesting contributions. I thank you both, Rik and Walter.
For now, what Rik has come up with fits my needs perfectly.

Iniciar sesión para comentar.

Más respuestas (1)

Walter Roberson
Walter Roberson el 23 de Dic. de 2022
If the requirement was that the bound variable would be a plain numeric value that could satisfy isnumeric and isdouble (to be passed as a parameter for example) then the answer would be that there is no provision for that in MATLAB.
It is especially the case that using a plain unindexed assignment will completely overwrite the target variable, removing any special attribute or ties it might have.
You would therefore need to encapsulate the behavior within a class, or you could encapsulate behaviors within functions.

Categorías

Más información sobre Environment and Settings en Help Center y File Exchange.

Productos


Versión

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by