Передача фактических значений в функцию обратного вызова в Matlab - PullRequest
2 голосов
/ 16 декабря 2011

давайте предположим следующий простой пример:

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

Есть ли более простой способ всегда передавать значения ACTUAL * для x и y в функцию обратного вызова вместо необходимости всегда обновлять ее в цикле? Спасибо!

Ответы [ 2 ]

4 голосов
/ 16 декабря 2011

Похоже, вы пытаетесь сохранить значение позиции щелчка мыши, а затем использовать эти значения как часть функции изменения размера (которая будет вызвана позже).Я бы сделал несколько изменений:

Во-первых, вместо цикла while используйте другой обратный вызов для захвата щелчка мыши.Например, вы можете использовать рисунок ButtonDownFcn обратный вызов, чтобы вызвать функцию, которая была разработана для захвата положения мыши в каком-то месте.

Во-вторых, есть лучшие способы сохранить положение мыши, и правопуть будет зависеть от вашего уровня квалификации и потребностей вашей программы.Вот некоторые из этих методов хранения данных:

  1. В аргументах для другого обратного вызова, как вы делаете сейчас.Это довольно больно, но, вероятно, работает.Таким образом, вы можете сохранить его, если он достаточно хорош для ваших нужд.

  2. Поле 'userdata' в большинстве объектов Matlab.Несколько человек подняли этот вопрос, и он будет работать нормально.Мне не нравится полагаться на это, потому что я всегда боюсь, что какой-то другой инструмент также захочет использовать поле пользовательских данных, и эти инструменты будут перезаписывать данные.

  3. A global значение переменной.Я также не люблю использовать глобальные переменные, по той же причине, по которой я не люблю использовать поле userdata.Но globals иногда так или иначе являются лучшим решением.Это, вероятно, самое простое решение с минимальными усилиями, если у вас есть только одна фигура за раз.(Несколько цифр приведут вас к решению userdata как к простейшему решению.)

  4. Предоставьте класс handle для хранения некоторых данных (т.е. x и y) и выдайте копиюэтого класса для каждого из двух обратных вызовов (ButtonDownFcn и ResizeFcn).Это позволяет двум функциям передавать данные, не загрязняя чужое пространство имен.Это мое любимое решение проблемы такого рода, поэтому я приведу более подробное описание ниже.


Для выполнения вышеуказанного варианта (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
3 голосов
/ 16 декабря 2011

Я не уверен, что вы на самом деле пытаетесь сделать - возможно, ваш простой пример скрыл ваши настоящие намерения - но вместо того, чтобы повторно устанавливать новую версию ResizeFcn, вы могли бы просто сохранить что-то в UserData свойство рисунка, и ваш ResizeFcn прочитал его при выполнении?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...