MATLAB Answers

GUI handles disappear after calling script

15 ビュー (過去 30 日間)
Gary Sherwin
Gary Sherwin 2018 年 7 月 26 日
コメント済み: Gary Sherwin 2018 年 7 月 28 日
I have a large GUI that updates several axes graphs in response to user input. The application utilizes a script to perform the plotting on the various axes. I have attached a smaller example that illustrates the issue. The first time I click either button, everything executes as expected. However, if I hit any button a second time I get the error:
Error using plot Parent must be a scalar graphics handle.
Error in testPlotScript (line 3) plot(testAxisView, handles.testData.x, handles.testData.y);
Error in ScriptCalledByCallbackTest>pushbutton1_Callback (line 86) testPlotScript(); ...
###################################################
Somehow, the GUI handles are disappearing.
FIRST BUTTON PUSH:#############################################
testAxisView =
Axes (axes1) with properties:
XLim: [0 1]
YLim: [0 1]
XScale: 'linear'
YScale: 'linear'
GridLineStyle: '-'
Position: [55.1429 8.2452 39.1429 17.7500]
Units: 'characters'
Show all properties
SECOND BUTTON PUSH:#############################################
testAxisView =
0×0 empty GraphicsPlaceholder array.
How do I get around this problem?

  0 件のコメント

サインインしてコメントする。

採用された回答

Benjamin Kraus
Benjamin Kraus 2018 年 7 月 26 日
The issue is your call to findobj and the HandleVisibility of the figure.
When you are calling findobj, you are not specifying where to search for the desired axes. Because you are not specifying where to look, MATLAB is looking within the "root object". Effectively, findobj is starting with groot (the root object) and asking for all the children. Then it is checking all the children to see if they are axes. Then it is checking the children of children to see if they are axes, etc. However, because the HandleVisibility of the figure is set to callback, the figure is not showing up in the Children list of the root object, so the output from findobj is empty.
You can find some more information about HandleVisibility on this doc page: Prevent Access to Figures and Axes.
It is a little strange to me that it is working the first time you press the button, but not working the second time you press the button. I'm not quite sure why that is happening, but I suspect it has something to do with the call to plot resetting the figure.
Regardless, the fix is simple: always pass objects when calling functions from your GUIDE code.
There are several ways you can do this:
Option 1: Pass the axes handle to testPlotScript.
This option involves updating your testPlotScript to accept an input argument. For example:
function testPlotScript(handles, testAxisView)
plot(testAxisView, handles.testData.x, handles.testData.y);
end
Now when you call testPlotScript, make sure to pass in the two input arguments:
testPlotScript(handles, handles.axes1)
Option 2: Pass just the handles structure to testPlotScript. For example:
function testPlotScript(handles)
plot(handles.axes1, handles.testData.x, handles.testData.y);
end
Now when you call testPlotScript, make sure to pass in the handles structure:
testPlotScript(handles)
Option 3: Pass the figure handle to testPlotScript and pass the figure handle to findobj. For example:
function testPlotScript(handles, fig)
testAxisView = findobj(fig, 'Type', 'axes', 'Tag', 'axes1')
plot(testAxisView, handles.testData.x, handles.testData.y);
end
Now when you call testPlotScript, make sure to pass in the two input arguments:
testPlotScript(handles, handles.figure1)

  1 件のコメント

Gary Sherwin
Gary Sherwin 2018 年 7 月 28 日
Benjamin:
I used option 2. It works perfectly.
Thank you.

サインインしてコメントする。

その他の回答 (1 件)

Benjamin Kraus
Benjamin Kraus 2018 年 7 月 26 日
I'm having trouble running your example. I think you are missing some pieces, including the file ScriptCalledByCallbackTest.m.
Regardless, some high-level graphics commands, including plot, call newplot to prepare the figure and axes for plotting. This command inspects the NextPlot property on both the figure and the axes to determine whether to (a) delete the axes and create a new one, (b) reset the axes, (c) or add to the existing axes.
I suspect what is happening is that NextPlot is being set to replace or replacechildren which means that a call to plot will delete the existing axes.
Add this to your testPlotScript to inspect the value of NextPlot:
testAxisView = findobj('Type', 'axes', 'Tag', 'axes1')
disp(testAxisView.NextPlot)
f = ancestor(testAxisView,'figure');
disp(f.NextPlot)
plot(testAxisView, handles.testData.x, handles.testData.y);
Let us know the value of NextPlot on both on the figure and axes. I suspect those are causing the issue you are seeing.
If not, try updating the attachments to make sure all the necessary files are included. DAA_Cert_SensorModelTest.m looks like a GUIDE generated file, but I don't see the corresponding .fig file, and I don't see the ScriptCalledByCallbackTest.m that matches ScriptCalledByCallbackTest.fig. Note: You cannot rename FIG or M files generated by GUIDE without breaking the association between the two. If you want to rename the files, you need to open them in GUIDE and choose "Save As".

  1 件のコメント

Stephen Cobeldick
Stephen Cobeldick 2018 年 7 月 27 日
Gary Sherwin's "Answer" moved here (and formatted):
Benjamin:
I replaced my code with your suggested changes. Here is my output.
I have also included the correct .m file
I ran into the file renaming issue that you mention. I was able to work through that. The tricky part there was going into the .fig properties and changing the names there as well.
Thank you.
ScriptCalledByCallbackTest
testAxisView =
Axes (axes1) with properties:
XLim: [0 1]
YLim: [0 1]
XScale: 'linear'
YScale: 'linear'
GridLineStyle: '-'
Position: [55.1429 8.2452 39.1429 17.7500]
Units: 'characters'
Show all properties
replace
f =
Figure (figure1) with properties:
Number: []
Name: 'ScriptCalledByCallbackTest'
Color: [0.9400 0.9400 0.9400]
Position: [135.8571 37.5625 112 32.3125]
Units: 'characters'
Show all properties
add
testAxisView =
0×0 empty GraphicsPlaceholder array.
No appropriate method, property, or field 'NextPlot' for class 'matlab.graphics.GraphicsPlaceholder'.
Error in testPlotScript (line 2)
disp(testAxisView.NextPlot)
Error in ScriptCalledByCallbackTest>pushbutton3_Callback (line 100)
testPlotScript();
Error in gui_mainfcn (line 95)
feval(varargin{:});
Error in ScriptCalledByCallbackTest (line 43)
gui_mainfcn(gui_State, varargin{:});
Error in
matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)ScriptCalledByCallbackTest('pushbutton3_Callback',hObject,eventdata,guidata(hObject))
Error while evaluating UIControl Callback.

サインインしてコメントする。

製品


リリース

R2018a

Community Treasure Hunt

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

Start Hunting!

Translated by