Getappdata and Setappdata not working within callback

Hi all,
I am having a problem where getappdata (within a callback) is not retrieving all of the information stored with setappdata.
I store the data like this:
setappdata(gcf, 'Subject', Subject)
which reports this (the appropriate data):
name: 'Testeroo'
folder: 'C:\Users\jx2\Dropbox\Cirxb\xg\inducti...'
device: 2
mode: 1
Settings: [1x1 struct]
Audio: [1x1 struct]
but when I getappdata like this
Subject = getappdata(gcf, 'Subject')
within a callback it reports this:
name: 'Testeroo'
folder: 'C:\Users\jx2\Dropbox\xb\Dxg\inducti...' (edited by me)
device: 2
mode: 1
Settings: [1x1 struct]
which is missing the Audio field. Any ideas?
Thanks!
EDIT! Here is more of the code so you guys will have a better chance of understanding. Thanks for all the help so far.
This function is called prior to to pressing a button in a GUIDE GUI.
function initSoundTest(handles)
set(handles.slMinLevel,'Enable','On')
set(handles.editMinLevel,'Enable','On')
set(handles.tbMinTest,'Enable','On')
Subject = getappdata(gcf, 'Subject');
sound_type_default=1;
Subject.Audio.maxLevel =max(Subject.Settings.sound.max_K, Subject.Settings.sound.max_B);
Subject.Audio.minLevel =min(Subject.Settings.sound.min_K, Subject.Settings.sound.min_B);
Subject.Audio.sound_type=sound_type_default;
setappdata(gcf, 'Subject', Subject)
createSounds(handles);
Subject.Audio.audioTimer = timer('TimerFcn', {@PlayAudio,gcf}, 'Period', ...
1, 'ExecutionMode', 'fixedRate', 'BusyMode', 'queue');
set(handles.editMinLevel, 'String', num2str(min(Subject.Settings.sound.min_K, Subject.Settings.sound.min_B)))
set(handles.slMinLevel, 'Value', min(Subject.Settings.sound.min_K, Subject.Settings.sound.min_B))
setappdata(gcf, 'Subject', Subject)
disp(getappdata(gcf,'Subject'))
disp(gcf)
The result of those disps:
name: 'Testeroo'
folder: 'C:\Users\jaw772\Dropbox\Circadian Lab\Dixon winning\inducti...'
device: 0
mode: 1
Settings: [1x1 struct]
Audio: [1x1 struct]
Figure (figure1) with properties:
Number: []
Name: 'SetupWizard'
Color: [0.9400 0.9400 0.9400]
Position: [135.6000 45 74.8000 30]
Units: 'characters'
Use get to show all properties
The part of the code that is called when a button is pressed AFTER that function is called (usually immediately after):
function tbMinTest_Callback(hObject, eventdata, handles)
% hObject handle to tbMinTest (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
button_state = get(hObject,'Value');
Subject = getappdata(gcf, 'Subject');
disp(getappdata(gcf,'Subject'))
disp(gcf)
if button_state == get(hObject,'Max')
set(hObject,'String','Running')
Subject.Audio.currentLevels = 'Min'; %%max or min??
Subject.Audio
start(Subject.Audio.audioTimer)
elseif button_state == get(hObject,'Min')
stop(Subject.Audio.audioTimer)
set(hObject,'String','Test')
end
setappdata(gcf, 'Subject', Subject)
NOTE: This causes an error! "the timer doesn't exist" basically.
The result of the disps and the unsuppressed output:
name: 'Testeroo'
folder: 'C:\Users\jaw772\Dropbox\Circadian Lab\Dixon winning\inducti...'
device: 0
mode: 1
Settings: [1x1 struct]
Figure (figure1) with properties:
Number: []
Name: 'SetupWizard'
Color: [0.9400 0.9400 0.9400]
Position: [135.6000 45 74.8000 30]
Units: 'characters'
Use get to show all properties
ans =
currentLevels: 'Min'

4 Comments

Tredwise - how many figures do you have? Are you sure that there is just the one so that gcf always refers to the same one? It may be better to try using the figure handle instead so that you always set and get from the same figure. (If you have more than one figure, then gcf may be changing to whichever one has focus and so the get may not necessarily refer to that which was set.)
That's a good point, thank you. All of this is within one figure (though there is another hidden figure) and I did check to see that gcf refers to the same figure in both cases. I will try changing references to gcf to the figure handle tomorrow to see if that helps.
Before (with audio field) :
Figure (figure1) with properties:
Number: []
Name: 'SetupWizard'
Color: [0.9400 0.9400 0.9400]
Position: [135.5000 42.5000 75 30]
Units: 'characters'
Use get to show all properties
After button press (no audio field):
Figure (figure1) with properties:
Number: []
Name: 'SetupWizard'
Color: [0.9400 0.9400 0.9400]
Position: [135.5000 42.5000 75 30]
Units: 'characters'
Use get to show all properties
Any other ideas are appreciated.
What did you do differently this time? Despite you saying that the audio field is there, now it is not. Did you just make a copy and paste error?
Yes this is the problem. and no. I'll edit it to add more information.

Sign in to comment.

 Accepted Answer

Saving it to the gcf doesn't save it. Use 0 instead. See the following code. Uncomment the gcf getappdata/setappdata lines if you want to see that gcf does not work. The code now has 0 instead of gcf and it works.
function test1
clc;
h = figure;
plot(1:10);
Subject.name = 'Testeroo';
Subject.folder = 'C:\Users\jx2\Dropbox\Cirxb\xg\inducti...';
Subject.device = 2;
Subject.mode = 1;
Settings.fielda = 4;
Subject.Settings = Settings;
a.field1 = 1;
Subject.Audio = a;
% Print to command line
Subject
% Store in appdata of the figure.
% setappdata(gsf, 'Subject', Subject) % Doesn't work
setappdata(0, 'Subject', Subject)
gcf % Print handle to window - must stop in debugger to see if Subject is attached.
% It's not.
% Now call GetStructure() and see what it is inside there
s = GetStructure();
% It's null if you use gcf but not if you use 0
function Subject = GetStructure()
gcf % Print handle to window
Subject = getappdata(0, 'Subject')

9 Comments

Your code has gsf instead of gcf??? I'll edit my code to have some more information.
I wouldn't use 0 or groot because this would cause a conflict with other applications. What happens when you close this one and reopen it? Unless you meticulously rmappdata'd, it's still there!
Instead, use the Tag of the figure in GUIDE to get the handle to it and set it there:
fig = handles.figure1; % "figure1" is 'Tag' of figure
setappdata(fig,'Subject',Subject)
Now any callback in this GUIDE app can reference handles.figure1, but no one outside can. And when the figure is closed it goes away.
Of course, IA is right for the reason why it isn't working, gcf is dynamic and might be (probably is) pointing at another figure that goes away.
I'll try replacing those references with the tag and get back to you.
no dice!!! I replaced all references to gcf with handles.figure1 and the same error occurs.
Nevermind, it is a logical problem! Thanks
You're welcome. By the way, I didn't say that. I said replace them with 0.
The other commenter said that. And after reviewing things a bit it looks like it was a combination of a logical error on my part and some kind of garbage collection issue in matlab. (maybe too much data stored too far down the list???)
Oh, sorry didn't see that because it was collapsed. It's strange though how it would have some of the fields but not all of them. I guess I'd need to code to check, but it sounds like it's a moot point because you have it solved now.

Sign in to comment.

More Answers (0)

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!