在Matlab中将实际值传递给回调函数 [英] Passing actual values to callback function in Matlab

查看:242
本文介绍了在Matlab中将实际值传递给回调函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设以下简单的例子:

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

解决方案

看起来你正试图存储鼠标点击位置的值,然后使用这些值作为resize函数(稍后将调用)的一部分。



首先,使用另一个回调代替 while 捕获鼠标点击。例如,您可以使用 ButtonDownFcn 回调来触发一个函数,该函数旨在将鼠标位置捕获到某个位置。



其次,有更好的方法来存储鼠标位置,正确的方式将取决于你的技能水平和你的程序的需要。这些存储数据的方法有:


  1. 在另一个回调的参数中,就像你现在做的那样。这是相当痛苦,但它可能工作。


  2. 大多数Matlab对象中的userdata字段。有几个人带来了这一点,它会工作正常。我不喜欢依赖这个,因为我总是害怕一些其他工具也想使用userdata字段,并且工具将覆盖数据。


  3. A 全局变量值。我不喜欢使用全局变量,出于同样的原因,我不喜欢使用 userdata 字段。但全局有时是最好的解决方案。如果你一次只有一个数字,这可能是最容易,最便宜的解决你的问题的解决方案。 (多个数字会促使您将 userdata 解决方案作为最简单的解决方案。)


  4. code> handle 类存储一些数据(即x和y),并为这两个回调( ButtonDownFcn ResizeFcn )。这允许两个函数传递数据,而不污染任何人的命名空间。这是我最喜欢的解决这类问题的方法,所以我将在下面给出更详细的描述。




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

  classdef ApplicationData<处理
属性(SetAccess = public,GetAccess = public)
x = [];
y = [];请注意,由于 ApplicationData / code> extends handle ,Matlab将其作为引用传递对象,对我们有用。



然后你可以创建一个这个类的实例,并把它给每个回调函数。

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

其中 mouseClickCapture 看起来像这样: / p>

  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)
%在这里使用
%dataPassingClass.x
%和
%dataPassingClass.y


let's assume the following easy example:

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

Is there any easier way to always pass the ACTUAL* values for x and y to the callback function instead of having to always update it in the loop? Thanks!

解决方案

It looks like you are trying to store the value of a mouse click position, and then use those values as a part of the resize function (which would be called at a later time). There are a few changes that I would make.

First, instead of the while loop, use another callback to capture the mouse click. For example, you could use the figure ButtonDownFcn call back to trigger a function which was designed to capture the mouse position into some location.

Second, there are better ways to store the mouse position, and the right way will depend on your skill level and the needs of your program. Some of these methods of storing data are:

  1. In the arguments to another callback, like you are doing now. This is pretty painful, but it probably works. So you could keep it if it is good enough for your needs.

  2. The 'userdata' field in most Matlab objects. A few people have brought this up, and it will work fine. I don't like to rely on this because I'm always afraid that some other tool will also want to use the userdata field, and the tools will overwrite data.

  3. A global variable value. I don't like to use globals either, for the same reason I don;t like to use the userdata field. But globals are sometimes the best solution anyway. This is probably the easiest, lowest effort solution to your problem if you only have one figure at a time. (Multiple figures would drive you towards the userdata solution as the easiest solution.)

  4. Provide a handle class to store some data (i.e. x and y) and give a copy of that class to each of the two callbacks (ButtonDownFcn and ResizeFcn). This allows the two functions to pass data, without polluting anyone else's namespace. This is my favorite solution to this sort of problem, so I'll give it a more detailed description below.


To execute option (4) above would need a class to store the data that looks something like this:

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

Note that since ApplicationData extends handle, Matlab treats it as a pass-by-reference object, which is useful to us.

Then you can create an instance of this class, and give it to each callback function.

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

Where mouseClickCapture looks something like this:

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

And your resizeCallback2 looks something like this:

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

这篇关于在Matlab中将实际值传递给回调函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆