Passing output from a ButtonDownFcn callback function

조회 수: 18 (최근 30일)
Jeroen
Jeroen 2024년 6월 11일
편집: Stephen23 2024년 6월 11일
Hello,
I am struggling with figuring out how to pass variables from a callback function (using ButtonDownFcn) to my main script.
Below is a simple example where I am trying to modify the example script from:
I simplified it below to just make the first function work and have two examples below:
- the original line (LINE A below), which doesn't pass my variable back and doesn't seem to allow me to define further output variables. Adding variables (double) to hIm also doesn't work (I guess because it is an image object?)
- the simple line (LINE B below) works to pass the output variable, but is not an option because it doesn't use the ButtonDownFcn anymore (which I need later).
clear all
close all
clc
im = imread('SENIAM_EMGEP1.jpeg');
% Gather data about the image, such as its size, and store the data in a structure that you can pass to callback functions.
sz = size(im);
myData.Units = 'pixels';
myData.MaxValue = hypot(sz(1),sz(2));
myData.Colormap = hot;
myData.ScaleFactor = 1;
% Display the image in an axes.
hIm = imshow(im);
% Specify a callback function for the ButtonDownFcn callback on the image. Pass the myData structure to the callback function. This callback function creates the line objects and starts drawing the ROIs.
hIm.ButtonDownFcn = @(~,~) startDrawing(hIm.Parent,myData); %% LINE A
myData = startDrawing(hIm.Parent,myData); %% LINE B
function myData = startDrawing(hAx,myData)
myData.test = 2;
% Create a line ROI object. Specify the initial color of the line and
% store the |myData| structure in the |UserData| property of the ROI.
h = images.roi.Line('Color',[0, 0, 0.5625],'UserData',myData);
end
I have had a similar issue with callback functions and thought it was time to seek help.
The answer provided here (https://nl.mathworks.com/matlabcentral/answers/563102-passing-a-variable-from-a-call-back-function-matlab-2020a) doesn't allow me to figure it out and I want to avoid using global variables.
Thanks for any advice.
  댓글 수: 1
Stephen23
Stephen23 2024년 6월 11일
편집: Stephen23 2024년 6월 11일
"I am struggling with figuring out how to pass variables from a callback function (using ButtonDownFcn) to my main script."
If you want to write GUIs then you need to change how you think: call the script (much better: function) from the callback. Once you do that, then writing complex GUIs will make much more sense:
Your current approach is limited to using e.g. WAITFOR or UIWAIT, which limits how much your GUI can do.

댓글을 달려면 로그인하십시오.

답변 (2개)

Adam Danz
Adam Danz 2024년 6월 11일
Callback functions do not have outputs or a clear workspace where the outputs would live. Instead, within a callback function you can store values within an object property that can be accessed outside of the callback function. If you're working with a custom app, add a private property to the app. If you're not working with app, you can store the property in an object's UserData property or use setappdata/getappdata. For example,
function startDrawing(hAx,myData)
% YOUR CODE THAT GENERATES h
h = ...
% APPEND LIST OF OBJECTS
existingLines = getappdata(hAx,'roiLines');
setappdata(hAx,'roiLine',[existingLines; h])
end

Steven Lord
Steven Lord 2024년 6월 11일
Callback functions for Handle Graphics objects don't return output arguments. [Where would it return those output arguments to? If the Handle Graphics object were created inside a function, there's no guarantee that function is still running when the callback gets executed. If another function (like another graphics object's callback) happened to be running at the time the callback returns, should it "poof" its outputs into that function's workspace? No.]
Rather than having your image object's ButtonDownFcn ignore its input arguments:
hIm.ButtonDownFcn = @(~,~) startDrawing(hIm.Parent,myData);
I'd have it accept at least the first argument (the graphics object whose callback is executing) and store whatever data you would have returned from the callback in a property of that object (or its Parent.) The UserData property for image objects is one way to do this. Then whatever needs that "output" argument can query the UserData property assuming it has access to the image object's handle. [And if it doesn't have access to the handle, is that an indication that it may not actually have "need to know" what's in the image's UserData property?]

카테고리

Help CenterFile Exchange에서 Interactive Control and Callbacks에 대해 자세히 알아보기

제품


릴리스

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by