Azzera filtri
Azzera filtri

Updating a string inside a callback

3 visualizzazioni (ultimi 30 giorni)
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

Risposta accettata

Sean de Wolski
Sean de Wolski il 21 Dic 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 Commento
Julián Francisco
Julián Francisco il 21 Dic 2011
@Sean de Wolski: Thank you very much for your answer.

Accedi per commentare.

Più risposte (1)

Jan
Jan il 21 Dic 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 Commento
Julián Francisco
Julián Francisco il 21 Dic 2011
@Jan Simon: Thank you so much for your explanation and suggestions.

Accedi per commentare.

Categorie

Scopri di più su Interactive Control and Callbacks in Help Center e File Exchange

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by