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

조회 수: 6 (최근 30일)
Paul
Paul 2022년 12월 21일
댓글: Paul 2022년 12월 29일
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
Paul
Paul 2022년 12월 23일
Thank you Stephen. I wil comment fully in the next few minutes.
Paul
Paul 2022년 12월 23일
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!

댓글을 달려면 로그인하십시오.

채택된 답변

Rik
Rik 2022년 12월 21일
편집: Rik 2022년 12월 22일
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
Walter Roberson
Walter Roberson 2022년 12월 28일
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 2022년 12월 29일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Walter Roberson
Walter Roberson 2022년 12월 23일
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.

카테고리

Help CenterFile Exchange에서 Environment and Settings에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by