Обновление строки внутри обратного вызова - PullRequest
0 голосов
/ 21 декабря 2011

Следующий код представляет собой графическое изображение земного шара, вращающегося на восток. У меня есть две кнопки, Spin и Stop. Оба используют одну и ту же функцию обратного вызова, hAnimaCallback. В частности, этот последний не работает. Я притворяюсь, что использую строки (имена) кнопок для создания переключателя, который останавливает движение. Однако я не могу изменить имя строки внутри цикла while и не понимаю, почему мой метод неправильный.

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

1 Ответ

1 голос
/ 21 декабря 2011

Похоже, что вы столкнулись с каким-то состоянием гонки из-за повторных вызовов drawnow в цикле while. Состояние изменяется на Стоп, когда вы нажимаете кнопку Стоп, но это быстро заметить. По сути, цикл while работает так быстро, как может работать MATLAB. Вместо drawnow команда pause(0.1) работает (с небольшими изменениями в логике кода):

az = 0;
spin = false;
  function hAnimaCallback(hObject,~)
    state = get(hObject,'String')
    if strcmp(state, 'Spin')
      spin = true;
    else
      spin = false;
    end

    while (spin)
      az = az + 0.01745329252;
      set(hgrot,'Matrix',makehgtform('zrotate',az));
      pause(0.1);
    end
  end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...