在Matlab中将实际值传递给回调函数

时间:2011-12-16 07:51:26

标签: matlab parameters callback

让我们假设以下简单示例:

f = figure;
plot(-10:10, (-10:10).^3, '*-r');
x = 1;
y = 1;
set(f, 'ResizeFcn', {@resizeCallback2, x, y});

while 1
    [x, y, button] = ginput(1);
    if(button ~= 1)
        break;
    end

    set(f, 'ResizeFcn', {@resizeCallback2, x, y});
end

%%--------------------------
function resizeCallback2(hFig, ~, foo, bar)    
    foo
    bar
end

是否有更简单的方法可以将x和y的 ACTUAL *值传递给回调函数,而不必总是在循环中更新它? 谢谢!

2 个答案:

答案 0 :(得分:4)

看起来您正在尝试存储鼠标单击位置的值,然后将这些值用作resize函数的一部分(稍后将调用它)。我会做一些改变。

首先,使用另一个回调来捕获鼠标单击,而不是while循环。例如,您可以使用图形ButtonDownFcn回调来触发一个旨在将鼠标位置捕捉到某个位置的功能。

其次,有更好的方法来存储鼠标位置,正确的方法取决于您的技能水平和程序的需求。其中一些存储数据的方法是:

  1. 在另一个回调的参数中,就像你现在正在做的那样。这非常痛苦,但它可能有效。如果它足以满足您的需求,您可以保留它。

  2. 大多数Matlab对象中的“userdata”字段。有几个人提出了这个问题,它会很好。我不喜欢依赖于此,因为我总是担心其他一些工具也会想要使用userdata字段,而工具会覆盖数据。

  3. global变量值。我也不喜欢使用全局变量,出于同样的原因我不喜欢使用userdata字段。但globals有时候是最好的解决方案。如果您一次只有一个数字,这可能是解决您问题的最简单,最省力的解决方案。 (多个数字会引导您走向userdata解决方案,这是最简单的解决方案。)

  4. 提供一个handle类来存储一些数据(即x和y),并将该类的副本提供给两个回调中的每一个(ButtonDownFcnResizeFcn) 。这允许两个函数传递数据,而不会污染任何其他人的命名空间。这是我对这类问题最喜欢的解决方案,所以我将在下面给它一个更详细的描述。


  5. 要执行上面的选项(4),需要一个类来存储看起来像这样的数据:

        classdef ApplicationData < handle
            properties (SetAccess = public, GetAccess = public)
                x = [];
                y = [];
            end
        end
    

    请注意,由于ApplicationData扩展了handle,因此Matlab会将其视为传递引用对象,这对我们很有用。

    然后,您可以创建此类的实例,并将其提供给每个回调函数。

        dataPassing = ApplicationData;
        set(f, 'ButtonDownFcn', @(x,y) mouseClickCapture(x,y,dataPassing));
        set(f, 'ResizeFcn',     @(x,y) resizeCallback2(x,y, dataPassing));
    

    mouseClickCapture看起来像这样:

        function mouseClickCapture(hAxis, ignored, dataPassingClass)
        mousePositionData = get(hAxis,'CurrentPoint');
        dataPassingClass.x = mousePositionData(1,1);
        dataPassingClass.y = mousePositionData(1,2);
    

    你的resizeCallback2看起来像这样:

        function resizeCallback2(h, ignored, dataPassingClass)
        %Do something here using 
        %dataPassingClass.x
        %and
        %dataPassingClass.y
    

答案 1 :(得分:3)

我不确定你真正想要做什么 - 也许你的简单例子掩盖了你的真实意图 - 但不是重复设置ResizeFcn的新版本,你能不能将某些内容存储在图中的UserData属性中,并让ResizeFcn读取它的执行时间吗?