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 件のコメント

Geoff Hayes
Geoff Hayes 2015 年 2 月 4 日
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.)
TREDWISE
TREDWISE 2015 年 2 月 4 日
編集済み: TREDWISE 2015 年 2 月 4 日
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.
Image Analyst
Image Analyst 2015 年 2 月 4 日
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?
TREDWISE
TREDWISE 2015 年 2 月 4 日
Yes this is the problem. and no. I'll edit it to add more information.

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

 採用された回答

Image Analyst
Image Analyst 2015 年 2 月 4 日

1 投票

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 件のコメント

TREDWISE
TREDWISE 2015 年 2 月 4 日
Your code has gsf instead of gcf??? I'll edit my code to have some more information.
Sean de Wolski
Sean de Wolski 2015 年 2 月 4 日
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.
Sean de Wolski
Sean de Wolski 2015 年 2 月 4 日
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.
TREDWISE
TREDWISE 2015 年 2 月 4 日
I'll try replacing those references with the tag and get back to you.
TREDWISE
TREDWISE 2015 年 2 月 4 日
no dice!!! I replaced all references to gcf with handles.figure1 and the same error occurs.
TREDWISE
TREDWISE 2015 年 2 月 4 日
Nevermind, it is a logical problem! Thanks
Image Analyst
Image Analyst 2015 年 2 月 4 日
You're welcome. By the way, I didn't say that. I said replace them with 0.
TREDWISE
TREDWISE 2015 年 2 月 4 日
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???)
Image Analyst
Image Analyst 2015 年 2 月 4 日
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.

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

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeCreating, Deleting, and Querying Graphics Objects についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by