在函数调用中保持对象持久化

keeping an object persistent across function calls

我早些时候问了一个关于在函数调用中保持变量持久性的问题,我想知道你是否可以对对象做类似的事情。

例如,如果我有一段这样的代码:

 function Gui(backofplayingcard,store,card)
 v = 1; 
 w = 1200;
 h = 550;
 f = figure('visible', 'off','color','white','position',[1 1 w h]);

 movegui(f,'center');

 set(f,'visible','on','name','matching game');



  % create 6 by 6 grid with a picture above a pushbutton for each location
  % on the grid

  for p = 1:6
  for w = 1:6

  subplot(6,6,((p - 1) * 6 + w) );
  imshow(backofplayingcard);

  button(v) =    uicontrol('Style','pushbutton','value',"some value dependent on p and w",'String','Flip!','Position',...
[[(152 * (w)) + ((w) * 10) + 25] [((7 - p) * 69) - ((p) * 10) + 33]  60 20],...
'Callback',{@flip});
 v = v + 1;

 end
 end
 end

有没有办法让我存储我用句柄调用的第一个对象。所以 例如:

      function flip(hObject,eventdata)
      persistent a;
      if isempty(a)
      handle1 = hObject;
      a = 1;
      else
      check1 = get(handle1,'value');
      check2 = get(hObject,'value');

     if check1 == check2

       disp('hello');

     else 
        disp('goodbye');

     end
     end
     end

这样 MATLAB 就会记住我调用的第一个对象。

正如我(不是很受欢迎)对你上一个问题的回答,我建议使用 handles 结构来存储回调之间共享的数据。

对于这种情况,我会为循环中创建的每个按钮添加一个自定义标签,这样可以很容易地知道按下了哪些按钮以及按下的顺序。例如,假设标签是在循环中创建的:

sprintf('Button %i',(p - 1) * 6 + w))

基本上每个按钮都会标有它的编号。如果需要,您可以将其更改为简单的数字。

为了获得所有按下的按钮的列表,您可以在 flip 函数中简单地垂直连接它们,这样您将得到一个元胞数组(在我的示例中,但它可以是数字数组取决于您选择的标签)包含每个被按下的按钮的 Tag。我还在句柄结构中添加了一个计数器,以防您想知道按下了多少个按钮...

我并不是要打扰您,但是将变量存储在 GUI 的句柄结构中是一种安全的方法,可以确保它们都可以从每个回调中轻松访问。

这是您的代码,添加了一些内容。你可以随心所欲地调整它。我添加了

%// ===== NEW =====

指出我添加的新内容。

您可以 copy/paste 将此代码作为一个新的 .m 文件,并在您每次按下按钮时查看 handles.ListFlip 的样子。

function CardGui

clc
clear

v = 1;
w = 1200;
h = 550;

%// Demo image 
backofplayingcard = imread('coins.png');

f = figure('visible', 'off','color','white','position',[1 1 w h]);

movegui(f,'center');

set(f,'visible','on','name','matching game');

%// ==== NEW ====
%// Initialize cell array containing list of buttons and counter.
handles.ListFlip = cell(1,1);
handles.flipCounter = 0;
%// =============

% create 6 by 6 grid with a picture above a pushbutton for each location
% on the grid

for p = 1:6
    for w = 1:6

        subplot(6,6,((p - 1) * 6 + w) );
        imshow(backofplayingcard);

        %// ==== NEW ====
        %// Added the buttons to the handles structure and gave them tags
        handles.button(v) =    uicontrol('Style','pushbutton','value',0,'String','Flip!','Position',...
            [(152 * (w)) + ((w) * 10) + 25 ((7 - p) * 69) - ((p) * 10) + 33  60 20],...
            'Callback',{@flip},'Tag',sprintf('Button %i',(p - 1) * 6 + w));
        v = v + 1;

    end
end

guidata(f,handles);

    function flip(hObject,~)

        handles = guidata(f);

        %// ==== NEW ====
        %// Get current button selected (using its tag)
        CurrentButton = get(hObject,'Tag');

        %// Add it to the list

        if handles.flipCounter  == 0
         handles.ListFlip = CurrentButton;   
        else
         handles.ListFlip = [handles.ListFlip;CurrentButton];
        end

        handles.flipCounter  = handles.flipCounter +1;
        %// =============

        guidata(f,handles)
    end
end

我按下 3 个按钮后命令 Window 中的示例输出:

Button 1
Button 3
Button 6

希望对您有所帮助。您可以将此代码与您收到的对上一个问题的答案结合起来,一切都会正常运行。