Filter löschen
Filter löschen

Event listener not picking up GUI data

18 Ansichten (letzte 30 Tage)
Matthew
Matthew am 19 Okt. 2018
Kommentiert: Matthew am 23 Okt. 2018
I've been trying to learn how to use an event listener (been using this as a basis: Simulink Signal Viewing using Event Listeners and a MATLAB UI.) and i seem to of found a strange error:
hf =
0x0 empty GraphicsPlaceholder array.
gui_name =
Event_listener_GUI
Error using guidata (line 87)
H must be the handle to a figure or figure descendent.
Error in Event_listener_GUI>localEventListener (line 232)
handles = guidata(mfilename)
Warning: Error occurred while evaluating listener callback.
The code that generates this is below (I removed the ';' on a few lines because I wanted to see what they were doing as well as un/commented out code from the simpleGUI.m file by Phil Goddard as i wanted to compare what his function was doing compared to mine, as it turns out his retrieves data from his GUI but mine displays what's above):
function localEventListener (block, eventdata)
% Get the application data
hf = findall(0,'Tag',mfilename)
gui_name = mfilename
%hf = gcbo
handles = guidata(mfilename)
% Get the handle to the line that needs updating
thisLineHandle = handles.ad.LineHandles([handles.ad.viewing.BlockHandle]...
==block.BlockHandle);
% Get current data for the line
xdata = get(thisLineHandles, 'XData');
ydata = get(thisLineHandles,'YData');
% Get the simulation time
sTime = block.CurrentTime;
data = block.InputPort(1).Data;
% only the last 1001 points worth of data is needed, the model sample time
% is 0,001 so this represents 1000 seconds of data
if length(xdata)<1001
newXData = [xdata sTime];
newYData = [ydata data];
else
newXData = [xdata(2:end) sTime];
newYData = [ydata(2:end) data];
end
% Display the new dataset
set(thisLineHandle,'XData',newXData,'YData',newYData);
% The axes limits might also need altering
newXLim = [max(0,sTime-10) max(10,sTime)];
set(handles.axes1,'XLim',newXLim);
For some reason when the model is started using the GUI (GUI remains open throughout) and the event listener is called it fails. any hope would be much appreciated!
  6 Kommentare
Matthew
Matthew am 22 Okt. 2018
Interesting, I made the GUI using Guide and it uses this line in its initialisation function to define the name of the GUI figure:
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @Event_listener_GUI_OpeningFcn, ...
'gui_OutputFcn', @Event_listener_GUI_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
Would it be worth forcing it to be a specific name somehow?
Adam
Adam am 23 Okt. 2018
You can change the 'Tag' in guide and I always do. By default it is just 'figure1' which is not very helpful. You still have to search for it afterwards if you rely on the tag, but if you are not able to keep the GUI handle itself for some reason it is the next best thing.

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Guillaume
Guillaume am 22 Okt. 2018
The problem has nothing to do with the name of the GUI. The problem is simply that guidata wants a figure handle (or other graphics handle). The name of an object doesn't matter, it's never going to be a graphics handle, and guidata(mfilename) will never work.
gcf is always going to return a graphics handle as long as you have at least one figure open. As Adam said, it's dangerous because the active figure may not actually be the expected one.
hf = findall(0,'Tag',mfilename); is also going to return a graphics handle. So that could be used for guidata. That would be a lot safer than gcf since the object tagged with mfilename is going to be your GUI figure.
The commented out hf = gcbo; is also another way to get a graphics handle. It's probably the simplest method, since it's always going to return the graphics handle of the object that triggered the callback.
  9 Kommentare
Guillaume
Guillaume am 23 Okt. 2018
I don't think you've understood how the code works. A tag can be anything you want and used for anything you want, but in this case its purpose is to make it easy for any any code to identify which figure is the UI figure. If a piece of code needs to access the figure but doesn't know what it is, it asks matlab to give it the figure with the given tag. If you know neither what the figure is nor what its tag is then you're lost.
So that
hf = findall(0,'Tag','Tag1');
is asking matlab: Of all the figures that are open which one is the one with tag 'Tag1'.
You don't have to use this mechanism. Instead you could ask for a figure with a given name. But once again, you'd have to know the figure name beforehand. Or you could use an external mechanism to share the figure handle. An often misused method for this is global variables. Do not use global variables!
If you have a handle to the figure you can of course get its tag:
get(hf, 'Tag')
%or
hf.Tag
But if you already have the figure handle, then you don't need to find it.
Matthew
Matthew am 23 Okt. 2018
You're probably right about the code, this is all new to me, but you have helped me solve my issue for which I am thankful!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Matthew
Matthew am 22 Okt. 2018
So it works when I use the following code:
function localEventListener (block, eventdata)
% Get the application data
hf = findall(0,'Tag',mfilename)
handles = guidata(gcf)
And this produces this output in the command window:
hf =
0x0 empty GraphicsPlaceholder array.
handles =
figure1: [1x1 Figure]
Model_Status: [1x1 UIControl]
Stop_Button: [1x1 UIControl]
Start_Button: [1x1 UIControl]
text2: [1x1 UIControl]
Gain_Value: [1x1 UIControl]
axes1: [1x1 Axes]
ModelName: 'event_listener_attempt'
ad: [1x1 struct]
output: [1x1 Figure]
EventHandle: {[1x1 handle.listener] [1x1 handle.listener]}
Removing the 'hf =...' line breaks the 'handles = ...' line for indeterminate reasons so I've left it in.
The example code I've been following however is structured like this:
% get the application data
hf = findall(0,'Tag',mfilename)
ad = guidata(hf)
And produces this in the command window:
hf =
Figure (simpleGUI) with properties:
Number: []
Name: 'Custom UI for controlling simpleModel.mdl'
Color: [0.9400 0.9400 0.9400]
Position: [0.3542 0.2852 0.2917 0.3898]
Units: 'normalized'
Show all properties
ad =
modelName: 'simpleModel'
tuning: [1x1 struct]
originalGainValue: '1'
gainValue: '1'
viewing: [1x2 struct]
originalStopTime: 'inf'
originalMode: 'external'
originalStartFcn: ''
modelAlreadyBuilt: 0
lineHandles: [14.0181 15.0095]
handles: [1x1 struct]
eventHandle: {[1x1 handle.listener] [1x1 handle.listener]}
But when I use that code in my version:
% Get the application data
hf = findall(0,'Tag',mfilename)
ad = guidata(hf)
It does this:
hf =
0x0 empty GraphicsPlaceholder array.
Error using guidata (line 87)
H must be the handle to a figure or figure descendent.
Error in Event_listener_GUI>localEventListener (line 228)
ad = guidata(hf)
Warning: Error occurred while evaluating listener callback.
Beyond using my, at best, workaround at the start of the post (as having more than one figure would break it) I haven't gotten it to work and am at a loss as to why it works in one file and not the other, ho-hum.

Kategorien

Mehr zu Event Functions finden Sie in Help Center und File Exchange

Produkte


Version

R2014b

Community Treasure Hunt

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

Start Hunting!

Translated by