如何在gui回调函数中等待运行函数的终止?

时间:2016-07-14 17:34:37

标签: matlab control-flow matlab-gui

我的程序在用户点击轴对象时运行一个函数。此函数使用光标的位置并将其进度显示为动画。我需要的是当用户点击新位置时停止当前正在运行的函数调用,然后为该新位置调用该函数。

我的代码是这样的(在我的原始代码中,我使用guidatahandles代替全局变量):

function TestUI
clc; clear variables; close all;
figure; axis equal; hold on;
xlim([0 100]); ylim([0 100]);
set(gca, 'ButtonDownFcn', @AxisButtonDownFcn);
global AnimateIsRunning
AnimateIsRunning = false;
end

function AxisButtonDownFcn(ah, ~)
C = get(gca,'CurrentPoint');
global xnow ynow AnimateIsRunning
xnow = C(1, 1); ynow = C(1, 2);
if AnimateIsRunning
    % ---> I need to wait for termination of currently running Animate
end;
Animate(ah, xnow, ynow);
end

function Animate(ah, x, y)
T = -pi:0.02:pi; r = 5;
global xnow ynow AnimateIsRunning
AnimateIsRunning = true;
for t = T
    if ~((xnow==x)&&(ynow==y))
        return;
    end;
    ph = plot(ah, x+r*cos(t), y+r*sin(t), '.');
    drawnow;
    delete(ph)
end
AnimateIsRunning = false;
end

我的问题是,任何较新的点击都会中断当前正在运行的功能,并使之前的Animate保持在堆栈中。它使上一个动画的最后一个绘图保持可见。更糟糕的是堆栈的大小似乎是8,更新的中断将存储在队列中!意思是用户只能更新位置8次。要查看问题,您可以运行上面的代码示例并重复单击轴对象。

现在,我想检查Animate中是否正在运行AxisButtonDownFcn,并等待其终止(或强制终止),然后使用新参数调用Animate。< / p>

1 个答案:

答案 0 :(得分:0)

memyself回复other question时,无法终止当前正在运行的Animate [或等待其终止] ,因为here在同一个线程中调用{1}}和AxisButtonDownFcn。所以可用的选项是:

  1. 使用全局变量,这很容易实现,但会增加复杂性和相互依赖性。您可以找到一些棘手的解决方案herehere
  2. 多线程,会尝试在单独的线程中运行处理部分和UI交互。它会更强大(如果您在使用线程方面经验丰富),但需要更多编码。这是http://cran.r-project.org/doc/manuals/r-release/R-admin.html#Uninstalling-under-OS-X
  3. 的详细实现

    我的解决方案基于全局变量的使用。它真的像我已经链接的解决方案,但他们都试图实现启动/停止按钮,而我需要停止当前进程并同时启动一个新进程:

    Animate

    它只是阻止function TestUI clc; clear variables; close all; figure; axis equal; hold on; xlim([0 100]); ylim([0 100]); set(gca, 'ButtonDownFcn', @AxisButtonDownFcn); global AnimateIsRunning AnimateIsRunning = false; end function AxisButtonDownFcn(ah, ~) C = get(gca,'CurrentPoint'); global xnow ynow AnimateIsRunning xnow = C(1, 1); ynow = C(1, 2); if ~AnimateIsRunning Animate(ah); end; end function Animate(ah) T = -pi:0.02:pi; r = 5; global xnow ynow AnimateIsRunning AnimateIsRunning = true; x = -1; y = -1; while ~((x==xnow)&&(y==ynow)) x = xnow; y = ynow; for t = T if ~((xnow==x)&&(ynow==y)) break; end; if ishandle(ah) ph = plot(ah, x+r*cos(t), y+r*sin(t), '.'); drawnow; if ishandle(ph) delete(ph) end end end end; AnimateIsRunning = false; end 被调用两次。如果它未运行,则会调用Animate,否则,它会通知当前正在运行的Animate有新请求。