Reference to non-existent field error occurring
Mostrar comentarios más antiguos
Matlab is generating the 'reference to non-existent field' error for my code. It is refering to one of my handles. Online it appears that this occurs if the field does not exist in the structure at the time the callback is set. This is not true for the offending field in my code as it is declared in the opening function and I have used guidata to update the handles structure. Is there another reason why this error should be occurring?
Error while evaluating uicontrol Callback
Reference to non-existent field 'verticalBin'.
Error in new_window_2>pushbutton4_Callback (line 190)
set(handles.verticalBin, 'enable', 'on');
Error in gui_mainfcn (line 96)
feval(varargin{:});
Error in new_window_2 (line 42)
gui_mainfcn(gui_State, varargin{:});
Error in @(hObject,eventdata)new_window_2('pushbutton4_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating uicontrol Callback
2 comentarios
Stephen23
el 29 de Mayo de 2017
@Aaron Smith: please edit your question and show us the complete error message. This means all of the red text.
Aaron Smith
el 29 de Mayo de 2017
Respuestas (1)
As mentioned in your other thread, your code would be much easier to read, if you use the auto-indentation.
The are some bugs in the code. E.g.:
% finishCellB = cell(length(FilesB)); Should be:
finishCellB = cell(1, length(FilesB));
Simplify your code:
if handles.option == 1 % If this button is pushed, Bin the corresponding file
handles = guidata(hObject);
binnedH = sum(handles.finishCellfull, 2);
handles.horizontalBin = stairs(binnedH);
guidata(hObject, handles);
elseif handles.option == 2 % If this button is pushed, Bin the corresponding file
handles = guidata(hObject);
binnedH = sum(handles.finishCellhalf, 2);
handles.horizontalBin = stairs(binnedH);
guidata(hObject, handles);
else % If this button is pushed, Bin the corresponding file
handles = guidata(hObject);
binnedH = sum(handles.finishCellquarter, 2);
handles.horizontalBin = stairs(binnedH);
guidata(hObject, handles);
end
Leaner:
handles = guidata(hObject);
if handles.option == 1
binnedH = sum(handles.finishCellfull, 2);
elseif handles.option == 2
binnedH = sum(handles.finishCellhalf, 2);
else
binnedH = sum(handles.finishCellquarter, 2);
end
handles.horizontalBin = stairs(binnedH);
guidata(hObject, handles);
Or even:
handles = guidata(hObject);
options = {'finishCellfull', 'finishCellhalf', 'finishCellquarter'};
field = options{handles.option};
handles.horizontalBin = stairs(sum(handles.(field), 2));
guidata(hObject, handles);
Less code, less chances for typos.
We still cannot run your code and therefore not reproduce the problem. And as in your other thread, I mentione, that you can examine what's going on using the debugger. Set breakpoints in the code and check, where the concerned field is existing and where it is missing. Then it will be a command in between, which has removed the field.
Can you confirm, that the field handles.verticalBin does exist inside the OpeningFcn in line 63? Set a breakpoint in this line to check this.
29 comentarios
Aaron Smith
el 29 de Mayo de 2017
Aaron Smith
el 29 de Mayo de 2017
@Aaron: This is a very basic question and you can check this very easily by your own:
C = cell(2)
D = cell(1, 2)
Type this in the command window and see, what happens. Do you want to create a {length(FilesB), length(FilesB)} cell matrix? You need to use debugging techniques to see, what's going on. Learn how to obeserve, what Matlab is doing. Otherwise you only guess, what your code does.
I do not even see, where you have created the field verticalBin initially. Are you sure, that is existing at all? If you are sure, why? Did you check it?
And if you add a breakpoint in the line 63, the code fails with an error in the previous line already? Did you create handles.option anywhere? If you later check:
if handles.option == 1
it seems like 'option' contains a number. But in the OpeningFcn you try to enable it:
set(handles.option, 'enable', 'on')
It is bewildering, that your code fails with a completely new problem, when I ask you to debug the mentioned problem. Did you run the code you have posted here? Did it fail before in the OpeningFcn already and you did not detect the problem?
I'm still convinced, that the solution will be very easy. The only difficulty is to determine, where the missing field is removed or finding out, if it was created at all. Using the debugger this is easy and done in some seconds. Unfortunately we cannot do this for you and without the FIG file we cannot run the code. But you can do this by your own. Learn how to use the debugger. Then programming gets a lot easier and efficient.
Aaron Smith
el 29 de Mayo de 2017
Jan
el 29 de Mayo de 2017
If handles.verticalBin is created in the callback of the radio button, how can
set(handles.verticalBin, 'enable', 'off');
run successfully in the OpeningFcn?
If the GUI is started, the figure is created and the OpeningFcn runs. Afterwards the callbacks are called, when their objects are activated.
For me it looks like the field handles.verticalBin is not created before it is used. This should concern horizontalBin also.
If teh contents of handles.verticalBin is "a binned version of the data", why do you try to set its 'Enable' property to 'off'? What exactly is "a binned version"? Is it a handle of a graphics object? If not, does is have an 'enable' property?
You create this in the pushbutton2_Callback:
handles.finishCellhalf = finishCellB{1};
and this in the OpeningFcn:
set(handles.finishCellhalf, 'enable', 'on');
This is strange. What do you think does 'enable', 'on' mean? Did you note, that the other lines in the OpeningFcn do not run for the same resaons?
I still do not get the impression, that you receive my message, that you have to use the debugger to solve the problem.
Set a breakpoint in the main function and step through the code line by line. Then you can identify the problems.
Aaron Smith
el 29 de Mayo de 2017
Stephen23
el 29 de Mayo de 2017
"Operational state of the uicontrol, specified as 'on', 'off', or 'inactive'. The Enable property controls whether or not the uicontrol responds to user interaction. These are the possible values:"
- " 'on' – The uicontrol is operational."
- " 'off' – The uicontrol is not operational and appears grayed-out."
- " 'inactive' – The uicontrol is not operational, but it has the same appearance as when Enable is set to 'on'."
Aaron Smith
el 29 de Mayo de 2017
Store the handles of the axes in the handles struct. Then you can specify the 'Parent' object, when you draw:
Axes1 = subplot(1,2,1);
Axes2 = subplot(1,2,2);
plot(Axes1, 1:10, rand(1:10));
plot(Axes2, 1:10, rand(1:10) + 2);
Or
plot(1:10, rand(1:10), 'Parent', Axes1); % Question of taste
Aaron Smith
el 29 de Mayo de 2017
Editada: Aaron Smith
el 29 de Mayo de 2017
Walter Roberson
el 29 de Mayo de 2017
You appear to be using GUIDE. If you created the axes at the GUIDE level then the axes will already exist and you will not need to create them.
Jan
el 30 de Mayo de 2017
@Aaron: You do not have to guess this or rely on the opinions of forum users, but you can check this by your own easily: Set a breakpoint in your code and examine the handles struct.
I tried to explain you the problem of the existing of the verticalBin field. Now we talk about the existence of the axes1 field. This is still very similar.
My understanding of 'enable' means is that if it is enabled ('on')
the button can be clicked and if it is not enabled ('off') the
button can not be clicked
But handles.verticalBin is not a button. Although MathWorks decided to call this struct "handles" (a bad idea!), it does not necessarily contain handles of GUI elements. In your case it contains some data, as far as I understand. Then 'enable'-ing is not meaningful.
Aaron Smith
el 30 de Mayo de 2017
Editada: Aaron Smith
el 30 de Mayo de 2017
Walter Roberson
el 31 de Mayo de 2017
You do not need to create the axes again in this situation.
Aaron Smith
el 31 de Mayo de 2017
Walter Roberson
el 31 de Mayo de 2017
Editada: Walter Roberson
el 31 de Mayo de 2017
When you use GUIDE, then the code it generates does an openfig() on the .fig file, which acts to re-create all the graphics that were saved in the .fig file, including any axes that you had used GUIDE to create. Then, after the openfig(), GUIDE searches for all tagged graphics handles in the figure, and attempts to create a field in the handles structure whose name is the same as the tag; if that works (which requires that the tag is a valid variable name), then the information will be saved into the handles structure that is available for the rest of the program execution.
TL;DR: YES. Why didn't you just test and save yourself a day?
Aaron Smith
el 31 de Mayo de 2017
Walter Roberson
el 31 de Mayo de 2017
Why didn't you just test and save yourself a day?
Jan
el 31 de Mayo de 2017
@Aaron: Matlab is a deterministic system. Variables defined in side a function, exist inside this function only. The list of variables of a function is called "workspace" of this function. If values should be shared with another function, they have to be provided as input or outputs, or e.g. through a shared struct like the "handles" using the guidata method.
GUIDE is a program to create GUIs in figures and the corresponding code for the callbacks. The handles of the objects created in GUIDE are stored automatically in the handles struct using fieldnames defined by something I don't know (I do not use GUIDE because it is not clear enough). I assume tha tag of the object is used. If so, and the axes is called "axes1", than the field handles.axes1 contains the handle of the axes. Then you do not have to write:
Axes1 = handles.Axes1
How did you get this idea? You would create a variables called "Axes1" inside the OpeningFcn, but you do not need it there. This would not have any magic effects to the other functions. There is no magic at all in Matlab. So do not waste time with inventing and asking magic ideas.
Again: You can simply set a breakpoint in the OpeningFcn and try by your own what happens, if you insert or remove this line. You can check the workspaces of the different callback functions and will find out, that creating a variable inside the OpeningFcn concerns the OpeningFcn only. It is another story, if you add a field to the handles struct there. But I do nmot have to explain this - simply try it.
Try to avoid all guessing like:
set(handles.finishCellhalf, 'enable', 'on');
Especially if you are a beginner, guessing how things work in Matlab will file very likely. Follow the examples in the documentation and do not insert some code anywhere which might be useful to do anything anywhere else. Remember that Matlab is the perfect opposite of Pirates of the Carribbean! :-)
Use the debugger to check, which fields are existing in the handles struct. Stop anywhere in the code and type this in the command window:
handles
This is much faster than asking the forum and it reveals all details about this struct.
Aaron Smith
el 1 de Jun. de 2017
Walter Roberson
el 1 de Jun. de 2017
Post your .m files and your .fig
Jan
el 1 de Jun. de 2017
@Aaron: I'm confused. Do you get the error "Undefined function or variable 'handles'" or "unknown field axes1"?
Where did you check the contents of the variable "handles"? I've suggested: "Use the debugger to check, which fields are existing in the handles struct. Stop anywhere in the code". So where did you stop? Or did you try this in the command window while the code is not running? Please explain such details. I do not have a crystal ball.
Use the debugger to find the contents of the handles struct: Set a breakpoint in the code, e.g. the OpeningFcn. Let handles = guidata(hObject) run and then check the fieldnames defined in this struct.
I changes the name of the axes handles in my code from
handles.Axes1 as I had it to handles.axes1
This is not clear. Where did you apply these changes? Did you check if "axes1" is an existing field?
Do you get my message? It seems like you try to program using erratic guesses of what Matlab does. This will not work. Sit down. Breath. Look at your code. Ask your self: Do I know what Matlab does, when I run this command? Can Matlab know what I want to do?
The same concerns the questions here: Do the readers have enough information to reconsider, what am I doing?
Good luck, Jan
Aaron Smith
el 1 de Jun. de 2017
Aaron Smith
el 1 de Jun. de 2017
Aaron Smith
el 2 de Jun. de 2017
Aaron Smith
el 2 de Jun. de 2017
Jan
el 2 de Jun. de 2017
How do you open the figure? By clicking on the FIG file? Wow, this would be a trivial solution for such an expanded discussion: You cannot start a GUI by opening the fig file. You have to run to M-function. Starting the M-function in the debugger or pressing the Run-button in the editor does this.
If this was the problem, you see how essential it is to explain exactly, what you are doing. If this is not the problem: I'm still convinced that you find a such an easy solution. Whenever Matlab seems to be magic, the user has done something he is not aware of.
Aaron Smith
el 2 de Jun. de 2017
Jan
el 2 de Jun. de 2017
As I said: Clicking on a FIG file opens the figure, but does not initialize e.g. the handles struct. Only running the M-file does this.
Categorías
Más información sobre Graphics Object Properties en Centro de ayuda y File Exchange.
Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!