Updating a string inside a callback

1 vue (au cours des 30 derniers jours)
Julián Francisco
Julián Francisco le 21 Déc 2011
The following code is a graphic rendering of the Earth globe spinning eastward. I have two push buttons, Spin and Stop. Both share the same callback function, hAnimaCallback. In particular, this latter does not work. I pretend to use the strings (names) of the push buttons to create a switch that stops the movement. However, I can not get to change the string name inside the while loop and I do not understand why my method is wrong.
function example
fh = figure('Menu','none','Toolbar','none','Units','characters');
T = 0:pi/100:2*pi;
Y = zeros(numel(T),3);
Y(:,1) = 7000*cos(T);
Y(:,2) = 7000*sin(T);
hPanAni = uipanel('parent',fh,'Units','characters','Position',...
[22.6 10.4 53 23],'title','Controls','FontSize',11,...
'FontAngle','italic','FontWeight','bold');
hIniAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.64 0.5 0.12],'String','Spin',...
'FontSize',10,'Callback',@hAnimaCallback);
hFinAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.26 0.5 0.12],'String','Stop',...
'FontSize',10,'Callback',@hAnimaCallback);
hPantSim = uipanel('Parent',fh,'Units','characters',...
'Position',[107.87 8 157.447 42],'BorderType','none','title',...
'Screen','FontSize',11,'FontAngle','italic',...
'FontWeight','bold');
hPantSimInt = uipanel('Parent',hPantSim,'Units','normalized','Position',...
[0 0 1 1],'BorderType','line','BackgroundColor','black');
ah4 = axes('Parent',hPantSimInt,'Units','normalized','Position',...
[0 0 1 1],'Color','none','Visible','off','DataAspectRatio',...
[1 1 1],'NextPlot','add');
rotate3d(ah4);
hgrot = hgtransform('Parent',ah4);
Resf = 6378;
maptext = imread('tierra.jpg');
[X, map] = rgb2ind(maptext,128);
[x,y,z] = sphere(50);
x = Resf*x;
y = Resf*y;
z = Resf*z;
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.Parent = hgrot;
props.Cdata = flipud(X); % it is necesary to do this for getting the
% appropiate image on the sphere
hsurf = surface(x,y,z,props);
colormap(map);
axis equal;
view([71 14]);
set(gcf,'Renderer','opengl')
drawnow;
line('parent',ah4,'XData',Y(:,1),'YData',Y(:,2),'ZData',...
Y(:,3),'Color','red','LineWidth',2);
line('parent',ah4,'XData',Y(end,1),'YData',Y(end,2),...
'ZData',Y(end,3),'Marker','o','MarkerSize',6,'MarkerFaceColor','b');
axis square equal vis3d;
view(3);
handles.XLim = get(ah4,'XLim');
handles.YLim = get(ah4,'YLim');
handles.ZLim = get(ah4,'ZLim');
xmin = handles.XLim(1);
ymin = handles.YLim(1);
zmin = handles.ZLim(1);
xmax = handles.XLim(2);
ymax = handles.YLim(2);
zmax = handles.ZLim(2);
set(ah4, 'XLim', [xmin xmax],'YLim', [ymin ymax],'Zlim',[zmin zmax]);
az = 0;
function hAnimaCallback(hObject,evt)
while (ishandle(fh))
state = get(hObject,'String'), % state should change between the states of Spin and Stop but this does not occur
if (strcmp(state,'Stop'))
break;
else
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
drawnow;
end
end
end
end

Réponse acceptée

Sean de Wolski
Sean de Wolski le 21 Déc 2011
Instead of using a while-loop I would highly recommend using a timer.
function hAnimaCallback(hObject,evt)
if isempty(timerfind) %spin
T = timer('tag','T','Period',0.001,'executionmode','fixedrate',...
'timerfcn',@make_her_spin);
start(T)
else %stop
T = timerfind('tag','T');
stop(T);
delete(T)
end
end
function make_her_spin(hObject,evt)
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
drawnow;
end
  1 commentaire
Julián Francisco
Julián Francisco le 21 Déc 2011
@Sean de Wolski: Thank you very much for your answer.

Connectez-vous pour commenter.

Plus de réponses (1)

Jan
Jan le 21 Déc 2011
If you hit the 'Spin' button, the callback function is started:
function hAnimaCallback(hObject,evt)
while (ishandle(fh))
state = get(hObject,'String')
if (strcmp(state,'Stop'))
break;
else
az = az + 0.01745329252;
set(hgrot,'Matrix',makehgtform('zrotate',az));
drawnow;
end
end
This loops runs infinitely. When drawnow is reached, it allows to reacting to events.
If you now hit the 'Stop' button, the callback function is called again and the break statement is reached. The callback returns and the other instance of it is still running! The value of hObject is not changed by calling another instance of the callback.
You can use a persistent variable to share data between different instances of a function. Or you can store the status flag using setappdata in the figure.
  1 commentaire
Julián Francisco
Julián Francisco le 21 Déc 2011
@Jan Simon: Thank you so much for your explanation and suggestions.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Interactive Control and Callbacks dans Help Center et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by