The below code is a basic example of my question,. This code generates a simple pushbutton and a display box to display the Value of the pushbutton. This is expected to read "0" when the code is run, as the pushbutton defaults to a value of 0 upon running. When the button is pressed (button is labeled 'Flight'), the callback function is called, where the pushbutton's value is updated to be 1 manually, and the display string is updated to be this new pushbutton value. I have commands to print to the command window the values of both of these variables before the button is pressed, as well as after.
My question is: when the button is pressed, the display string is updated to be "1" but the final pushbutton value is still 0. Why is this? Why is it not "1" as it's been assigned? Thanks
close all
% create figure
f = figure;
% create a pushbutton
poo.Button = uicontrol('Style','pushbutton', ...
'Parent',f,...
'Position',[20,20,40,40],...
'String', 'Flight',...
'HorizontalAlignment', 'center',...
'Callback',{@continueFcn});
% create a display box for the value of the pushbutton
poo.disp = uicontrol('Style','text',...
'Parent',f, ...
'Position',[80,80,20,20],...
'String', num2str(poo.Button.Value),...
'HorizontalAlignment', 'center');
% store the poo struct as the handle of the figure, f
guidata(gcf,poo);
% print the inital values of the display string and button value
fprintf(poo.disp.String)
display(poo.Button.Value)
% figure waits
uiwait(gcf)
% retrieve the new data from the figure
poo2 = guidata(gcf);
% print the updated values of the display string and button value
fprintf(poo2.disp.String)
display(poo2.Button.Value)
% callback for the pushbutton
function continueFcn(~,~)
poo2 = guidata(gcf);
% set the button value to be 1
set(poo2.Button,'Value',1)
% set the display string to be value of the pressed button -- 1
set(poo2.disp,'String',num2str(poo2.Button.Value))
% store the new poo2 struct as the gcf's data
guidata(gcf,poo2)
% resume
uiresume(gcf)
end

 채택된 답변

Walter Roberson
Walter Roberson 2023년 2월 7일

1 개 추천

The problem is not with guidata. guidata is holding the handle of the object, not the values associated with properties. There is no benefit to using guidata(gcf, poo2) if you are not changing a value directly at the poo2 level .
The problem is that uicontrol pushbutton only has Value equal to its Max during the time that the callback is being serviced, and it is reset to the Min value after the callback returns. pushbutton Value is not persistent.
If you want a control that holds value after return, you should be using togglebutton

댓글 수: 2

Benjamin Sorel
Benjamin Sorel 2023년 2월 7일
편집: Benjamin Sorel 2023년 2월 7일
Thank you, the difference between pushbutton and togglebutton makes sense.
As a follow up, maybe this addresses the core question about what using guidata() with two inputs really does:
This code is a simplified version of the first code, where the display text uicontrol originally says 'old'. The callback function for the button changes the property 'String' to be "new". When the code resumes, I print out the 'String' property of poo, not poo2. Even though I never called guidata(gcf,poo2) to update the gcf handle, the poo struct updated itself. Why does this happen when I only modify poo2, not poo?
close all
% create figure
f = figure;
% create a pushbutton
poo.Button = uicontrol('Style','pushbutton', ...
'Parent',f,...
'Position',[20,20,40,40],...
'String', 'push',...
'HorizontalAlignment', 'center',...
'Callback',{@continueFcn});
% create a display box for the value of the pushbutton
poo.disp = uicontrol('Style','text',...
'Parent',f, ...
'Position',[80,80,30,30],...
'String', 'old',...
'HorizontalAlignment', 'center');
% store the poo struct as the handle of the figure, f
guidata(f,poo);
% print the inital values of the display string
fprintf(poo.disp.String)
% figure waits
uiwait(f)
% retrieve the new data from the figure
poo2 = guidata(f);
% print the updated values of the display string and button value
fprintf(poo.disp.String)
% callback for the pushbutton
function continueFcn(~,~)
poo2 = guidata(gcf);
% set the display string to be value of the pressed button -- 1
set(poo2.disp,'String','new')
% store the new poo2 struct as the gcf's data
% guidata(gcf,poo2)
% resume
uiresume(gcf)
end
The key thing to understand is that poo.disp and poo2.disp refer to the same object (the textbox uicontrol).
You could say
xxxx = guidata(gcf);
fprintf(xxxx.disp.String)
and it would work. It doesn't matter that you call it poo in one place and poo2 in another place, the names poo and poo2 are local to their functions.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Interactive Control and Callbacks에 대해 자세히 알아보기

태그

질문:

2023년 2월 7일

댓글:

2023년 2월 7일

Community Treasure Hunt

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

Start Hunting!

Translated by