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

在Matlab中将实际值传递给回调函数,matlab,parameters,callback,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,

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

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的实际*值传递给回调函数,而不必总是在循环中更新它?
谢谢

我不确定您实际想做什么-也许您的简单示例模糊了您的真实意图-但与其反复设置新版本的
ResizeFcn
,不如将一些内容存储在图形的
UserData
属性中,并让您的
ResizeFcn
在执行时读取它?

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

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

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

  • 在另一个回调的参数中,就像您现在所做的那样。这很痛苦,但可能有效。因此,如果它足够满足您的需要,您可以保留它

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

  • 一个
    全局
    变量值。我也不喜欢使用globals,原因和我不喜欢一样;我不想使用
    userdata
    字段。但无论如何,
    globals
    有时是最好的解决方案。如果一次只有一个数字,这可能是解决问题最简单、最省力的方法。(多个数字将促使您使用
    userdata
    解决方案作为最简单的解决方案。)

  • 提供一个
    句柄
    类来存储一些数据(即x和y),并将该类的副本提供给两个回调中的每一个(
    ButtonDownFcn
    ResizeFcn
    )。这允许这两个函数传递数据,而不会污染其他任何人的命名空间。这是我最喜欢的解决这类问题的方法,因此我将在下面对其进行更详细的描述


  • 要执行上面的选项(4),需要一个类来存储如下所示的数据:

        classdef ApplicationData < handle
            properties (SetAccess = public, GetAccess = public)
                x = [];
                y = [];
            end
        end
    
        function mouseClickCapture(hAxis, ignored, dataPassingClass)
        mousePositionData = get(hAxis,'CurrentPoint');
        dataPassingClass.x = mousePositionData(1,1);
        dataPassingClass.y = mousePositionData(1,2);
    
        function resizeCallback2(h, ignored, dataPassingClass)
        %Do something here using 
        %dataPassingClass.x
        %and
        %dataPassingClass.y
    
    其中,
    mouseClickCapture
    看起来像这样:

        classdef ApplicationData < handle
            properties (SetAccess = public, GetAccess = public)
                x = [];
                y = [];
            end
        end
    
        function mouseClickCapture(hAxis, ignored, dataPassingClass)
        mousePositionData = get(hAxis,'CurrentPoint');
        dataPassingClass.x = mousePositionData(1,1);
        dataPassingClass.y = mousePositionData(1,2);
    
        function resizeCallback2(h, ignored, dataPassingClass)
        %Do something here using 
        %dataPassingClass.x
        %and
        %dataPassingClass.y
    
    您的
    resizeCallback2
    如下所示:

        classdef ApplicationData < handle
            properties (SetAccess = public, GetAccess = public)
                x = [];
                y = [];
            end
        end
    
        function mouseClickCapture(hAxis, ignored, dataPassingClass)
        mousePositionData = get(hAxis,'CurrentPoint');
        dataPassingClass.x = mousePositionData(1,1);
        dataPassingClass.y = mousePositionData(1,2);
    
        function resizeCallback2(h, ignored, dataPassingClass)
        %Do something here using 
        %dataPassingClass.x
        %and
        %dataPassingClass.y
    

    我同意,标准模式是使用
    UserData
    。这比更改
    ResizeFcn
    要清楚得多。谢谢,我不知道有这样一个字段来存储东西。。。但我仍然需要在每次迭代中更新UserData的值。没错,为什么这是个问题?你到底想做什么,而不是简单的例子?谢谢,我真的很喜欢你的方法。我特别喜欢它,因为我试图做的事情实际上是一个与“OOP”有关的问题:我的意思是,我有大约10个变量,我需要从一个函数到另一个函数,所有这些变量都与一个“对象”有关,因此创建某种对象并使用其属性是一个好主意:)谢谢!此外,我喜欢您不使用ginput的方法:当某个操作发生时,我想以某种方式从另一个函数中中止ginput()时,我已经遇到了一个问题,但我不能,因为没有实际的单击!可能只有一个问题,这是我在MatlabNewsReader中发现的:句柄类可能很慢:我很想知道您是否在应用程序中发现同样的慢性能。我有两个理由怀疑你不会。首先,这篇文章是使用2009a编写的,Mathworks通常会在1-2版本之后修复类似的性能问题。第二,在那篇文章中最奇怪的事情是句柄类中的类似操作非常不同,而不是句柄类都很慢。知道了这一点(看起来很奇怪),你可能可以解决任何速度问题。也就是说,我从未使用过性能是一个大问题的句柄类,所以我不知道。到目前为止我还没有,但我还没有真正将“繁重”的计算放入句柄类,因为还没有必要:)但是,我必须再次说声谢谢,我已经使用这个解决方案好几个星期了,我真的很喜欢:)非常优雅和流畅!类似