Reference to non-existent field error occurring
4 次查看(过去 30 天)
显示 更早的评论
Aaron Smith
2017-5-29
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 个评论
Stephen23
2017-5-29
@Aaron Smith: please edit your question and show us the complete error message. This means all of the red text.
Aaron Smith
2017-5-29
Done. It specifies the line where the error arises. Depending on which push button is used it will either be 116, 153 or 190 as the same line exists in all three
回答(1 个)
Jan
2017-5-29
编辑:Jan
2017-6-2
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 个评论
Aaron Smith
2017-5-29
Thanks Jan.
What does the added 1 in the line finishCellB = cell(1, length(FilesB)); do?
I will go through the code with the debugger now to check it out. What I don't understand is how the handles.verticalBin field can not exist if I have included it in the code?
Aaron Smith
2017-5-29
When I added a breakpoint at line 63 it says that the handles.option field does not exist. I must be missing something about how these fields can not exist at certain point in the code
Jan
2017-5-29
编辑:Jan
2017-5-29
@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
2017-5-29
The field is created inside the radio button callback. It is a binned version of the data from the pushbutton callback handles.finishCell.
The code runs fine when run until the verticalBin error arises. You are correct about the enable statement for the handles.option field though. it is only a numerical value and i have declared it like an app. This is a mistake. I should have declared it differently
Jan
2017-5-29
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
2017-5-29
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
Stephen23
2017-5-29
"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
2017-5-29
I removed all references to the verticalBin and horizontalBin fields before their creation and the window is working. There is just one small problem. I have two axes in my gui and I would like to plot the data from the pushbutton and the data from the radio button on different axes but both are being plotted on the same one. I should be able to find an easy fix for this in previous mathworks questions though. Thanks
Jan
2017-5-29
编辑:Jan
2017-5-29
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
2017-5-29
编辑:Aaron Smith
2017-5-29
Will I give a handle field to the axes or can I specify where to plot the data in the callbacks themselves? Does a handle field already exist for the axes or do I need to create them?
Walter Roberson
2017-5-29
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
2017-5-30
@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
2017-5-30
编辑:Aaron Smith
2017-5-30
Do I need to write the handles.Axes, the existence of which i am checking with the breakpoints? I am unclear on this and the debugging page on Mathworks is not very enlightening on this. https://uk.mathworks.com/help/matlab/matlab_prog/debugging-process-and-features.html
I realise this query probably seems overly simple to you but I am still a novice with Matlab and the constant use and reuse of terminology, the meaning of which appears to me to change depending on the person commenting. Thanks for your continued assistance Jan. Like Walter said previously, since I have created the window in guide and have created the axes, i should be able to just name them handles.axes1 or handles.axes3 right?
Walter Roberson
2017-5-31
编辑:Walter Roberson
2017-5-31
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
2017-5-31
What I was unsure about is if I simply write handles.Axes1 or handles.Axes3 in my callbacks will it work fine or do I need to write a statement somewhere, perhaps in the opening function, that says say Axes1 = handles.Axes1 before I can use the handles
Jan
2017-5-31
@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
2017-6-1
This simply presents an error: Undefined function or variable 'handles'. I changes the name of the axes handles in my code from handles.Axes1 as I had it to handles.axes1 since in the guide editor the axes is named in all lower case but the same errors occurred stating there was a reference to an unknown field axes1
Jan
2017-6-1
@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
2017-6-1
I ran the code using the debugger. I typed handles in the command window. This is when the undefined function or variable handles error occurred. I placed breakpoints after the opening function and at a number of other points in the code (i created new breakpoints each time, deleting the old ones). The same error occurred. The code was certainly running as i selected run in the drop down from the debugger and new_window_2 appeared in the commmand window.
The reason I changed the A in axes to an a is because i opened the guide editor and saw they it was lower case.
Aaron Smith
2017-6-1
I just retried using the window and the code is now working correctly. The code is the same code that presented errors before so I am not sure what has changed. Thanks for the help all.
Aaron Smith
2017-6-2
Today, despite no changes having been made to the code again, the same error has began occurring again:
Error while evaluating uicontrol Callback
Reference to non-existent field 'axes1'.
Error in new_window_2>pushbutton1_Callback (line 152)
contourf(finishCell{2}, 'parent', handles.axes1);
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('pushbutton1_Callback',hObject,eventdata,guidata(hObject))
My best guess is that perhaps there was still a breakpoint installed in the code but I am nearly certain that there wasn't and I do not see how this would make the code work when it had not worked previously. Any ideas?
Aaron Smith
2017-6-2
I have run the code using the debugger and now the window works perfectly well. Why would the code be working when run with the debugger but not otherwise?
Jan
2017-6-2
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
2017-6-2
Yeah, I have been opening the figures by clicking on the .fig file. I just tried running it from the code and it works perfectly fine. I am not sure what the problem was
Jan
2017-6-2
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Interactive Control and Callbacks 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!发生错误
由于页面发生更改,无法完成操作。请重新加载页面以查看其更新后的状态。
您也可以从以下列表中选择网站:
如何获得最佳网站性能
选择中国网站(中文或英文)以获得最佳网站性能。其他 MathWorks 国家/地区网站并未针对您所在位置的访问进行优化。
美洲
- América Latina (Español)
- Canada (English)
- United States (English)
欧洲
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
亚太
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)