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

时间:2015-04-20 17:56:12

标签: matlab user-interface scope

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

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

 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就会记住我调用的第一个对象。

1 个答案:

答案 0 :(得分:3)

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

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

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

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

为了获得所有按下的按钮的列表,你可以简单地在flip函数中将它们连接起来,这样你就会有一个单元格数组(在我的例子中,但是这可能是一个数字数组,具体取决于在你选择的标签上)包含按下的每个按钮的Tag。我还在句柄结构中添加了一个计数器,以防你想知道按下了多少个按钮......

我并不是故意要解决这个问题,但是将变量存储在GUI的句柄结构中是一种安全的方法,可以确保每次回调都可以轻松访问它们。

所以这里是你的代码,有一些补充。你可以随意调整它。我添加了

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

指出我添加的新内容。

您可以将此代码复制/粘贴为新的.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个按钮后,命令窗口中的示例输出:

Button 1
Button 3
Button 6

希望有所帮助。您可以将此代码与您在上一个问题中收到的答案结合起来,并且所有答案都能正常运作。