Appdesigner Edit Field (Numeric) won't update values.

Hi. I have 2 Edit Fields in my app - "Delay" and "Step". The goal is to set the step size and update the delay value. It is in principle working, but only if I change the two values every time. If I want to keep the step size at 20, I would expect that the Delay value would increase by 20 every time I hit the enter button. Moreover, this was working with the Guide, but when I transferred to Appdesigner recently (by using the migration functionality), I noticed that the Delay value would update only when I change the step size (or the Delay value itself). Here is my code. You can see the old Guide-style code lines commented, as well.
% Value changed function: pumpdelay
function pumpdelay_Callback(app, event)
% Create GUIDE-style callback args - Added by Migration Tool
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% hObject handle to pumpdelay (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of pumpdelay as text
% str2double(get(hObject,'String')) returns contents of pumpdelay as a double
pumpdelay = str2num(app.pumpdelay.Value)
delaystep = str2num(app.delaystep.Value)
pumpdelay = pumpdelay + delaystep
app.pumpdelay.Value = num2str(pumpdelay); % Set
% pumpdelay = str2num(get(handles.pumpdelay, 'String'));
% delaystep = str2num(get(handles.delaystep, 'String'));
% pumpdelay = pumpdelay + delaystep;
% set(handles.pumpdelay, 'String', num2str(pumpdelay));
% guidata(hObject, handles);
% CARS_GUI_2pulse_18('calculate_Callback',handles.calculate,[],handles);
end
% Value changed function: delaystep
function delaystep_Callback(app, event)
% Create GUIDE-style callback args - Added by Migration Tool
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% hObject handle to delaystep (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of delaystep as text
% str2double(get(hObject,'String')) returns contents of delaystep as a double
pumpdelay = str2double(app.pumpdelay.Value)
delaystep = str2double(app.delaystep.Value)
pumpdelay = pumpdelay + delaystep
app.pumpdelay.Value = num2str(pumpdelay); % Set
% pumpdelay = str2num(get(handles.pumpdelay, 'String'));
% delaystep = str2num(get(handles.delaystep, 'String'));
% pumpdelay = pumpdelay + delaystep;
% set(handles.pumpdelay, 'String', num2str(pumpdelay));
% guidata(hObject, handles);
end

7 commentaires

Any help?
Mario Malic
Mario Malic le 1 Nov 2020
Modifié(e) : Mario Malic le 1 Nov 2020
Hello,
I forgot to reply to this one, so, I would suggest you first to get rid of str2double, num2str and so on in your App Designer code. If your Edit Field is numeric, so is your input.
Second, It is in principle working, but only if I change the two values every time. If you consider any of your callback functions, The Edit Field for the app.pumpdelay.Value is set only when you change the number, then, the callback is executed and component's property gets the value.
You can set the value for app.pumpdelay.Value in the Component Browser, or programmatically by assigning it in StartupFcn, do the first one for now.
You have also mentioned that you have an Enter button - to solve the task in the easiest way (if I understood it correctly), you can just assign component properties within the Push Button callback. Starting values for properties are still needed.
function Push_Button_Callback(app, event)
app.pumpdelay.Value = app.pumpdelay.Value + app.delaystep.Value
end
I am reading my comment now, and it seems to me that it's improperly written because there's plenty of intormations in few sentences. Once when issues are simplified, we can solve it one by one.
Mario,
Thank you very much for your input! You are absolutely right that there is plenty of information in this string, and I probably confused you from the very beginning. Let's not focus on str2double, num2str, etc.: these are left from the old Guide-style code, and to emphasize it one more time, the code was working there. I also confused you about the "enter button", that was supposed to be the "enter" key of the keyboard, which when applied, should run the code of that specific callback.
I set the the value in the Component Browser, but that only changes the default value, right?
Lastly, I am not sure I understood your following point: "If you consider any of your callback functions, The Edit Field for the app.pumpdelay.Value is set only when you change the number, then, the callback is executed and component's property gets the value." I thought the code that I copy-pasted in the original post sets the app.pumpdelay.value, regardless that value (and/or the value of delaystep) is changed or not. If this is not the case, then how I set the value? I also tried the drawnow function, but that did not help either. Maybe I am using these functions in wrong lines.
Mario Malic
Mario Malic le 2 Nov 2020
Modifié(e) : Mario Malic le 2 Nov 2020
Hello,
Callback is the type of function that is executed under certain circumstances, in your case:
% Value changed function: DelayStepEditField
function DelayStepEditFieldValueChanged(app, event)
app.PumpDelayEditField.Value = app.PumpDelayEditField.Value + app.DelayStepEditField.Value;
end
This code will run when you change the Delay Step value (you can either press enter, or click elsewhere on the UI to finish input).
The value in the Component Browser is the default one, correct. Assume that you run your code, without having these default values. If you write a value in one of the components, let's say DelayStep, and your callback says to calculate PumpDelay = PumpDelay+DelayStep, it won't work because PumpDelay is not defined.
>> a.Value = []
a =
struct with fields:
Value: []
>> b.Value = 5
b =
struct with fields:
Value: 5
>> a.Value + b.Value
ans =
[]
There are two ways to set the default values, one is that you're familiar with, through the component browser, and second is through the StartupFcn. This function runs after components have been created and will overwrite the default values defined in component browser.
I have attached the demo application, I think this should help you, also there are few tutorial apps that cover stuff like this in minutes, so make sure you do them, as they are super helpful!
Hello Mario,
I am so thankful for your time and efforts... You even put together a demo app for me.
I might be giving a very strong statement now, but I think together we found a bug related to EditField in the Appdesigner. In your demo app, please keep the Delay Step at the default value 20 and click on the Calculate button a couple times. The Pump Delay value 100 will increase by 20 every time. Now click on the Delay Step Editfield box (so the cursor is there) and hit the enter key several times... nothing happens. Now set the Delay Step to 21 and hit enter. It will increase the Pump Delay value by 21, but ONLY ONCE. The single-line code is exactly the same in both "Button pushed function: CalculateButton" and "Value changed function: DelayStepEditField" callbacks, but in one case it works and in the other it does not.
I have explained when are callbacks executed above. In your case, the callback is Value Changed Function which means, the callback will be executed when the value is changed. So, if you're deleting and writing the same number (without clicking anywhere else but the Edit Field), the Pump Delay value will not change.
If you would like to do the calculation using the Enter button, then you need to add another callback function called WindowKeyPressFcn, here's an example code that needs to be edited to fit this example - link.
Bonus points:
This is a simple calculation that's repeated over three callbacks, you can create a helper function and just call the function instead of code to calculate.
function Calculate(app)
app.PumpDelayEditField.Value = app.PumpDelayEditField.Value + app.DelayStepEditField.Value;
end
zeytun
zeytun le 10 Déc 2020
Hello Mario,
I decided to go with a "Push Botton" and that worked nicely. Can you please copy-paste your following comment as a separate answer, so I can accept it?
function Push_Button_Callback(app, event)
app.pumpdelay.Value = app.pumpdelay.Value + app.delaystep.Value
end
I have a follow-up question though :) Every time I hit this new Push Button, I want it to change the value of app.pumpdelay (which it does now), and in addition to that, I want to activate the functionality of another old Push Button (called "Calculate"), which mainly does some plotting. In the old Guide I was implementing this throught the following lines:
guidata(hObject, handles);
mycodename('calculate_Callback',handles.calculate,[],handles);

Connectez-vous pour commenter.

 Réponse acceptée

Hello,
Based on the comment section, callback should be written this way
function Push_Button_Callback(app, event)
app.pumpdelay.Value = app.pumpdelay.Value + app.delaystep.Value
CalculateSmth(app)
end
If you create a helper function in your app, just call it, there's no need for another callback in App Designer. Just a reminder that you can not use variables that are defined in another callbacks. Reference the values from app components, or create a property to get around it.
function CalculateSmth(app)
% code
end

2 commentaires

zeytun
zeytun le 10 Déc 2020
Thanks!
calculate_Callback(app) did not work though, I am guessing because my app was converted from Guide. I am not using helper functions, need to spend some time to learn how to implement them in my code (looks very useful). Here is the error message...
Not enough input arguments.
Error in ultifemto/calculate_Callback (line 389)
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event);
%#ok<ASGLU>
Error in ultifemto/StepButtonPushed (line 2337)
calculate_Callback(app)
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 386)
Error while evaluating Button PrivateButtonPushedFcn.
zeytun
zeytun le 10 Déc 2020
Now it worked!!! I had to write calculate_Callback(app, event). Learning is fun :)

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

Produits

Version

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by