在函数调用中保持对象持久化
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
希望对您有所帮助。您可以将此代码与您收到的对上一个问题的答案结合起来,一切都会正常运行。
我早些时候问了一个关于在函数调用中保持变量持久性的问题,我想知道你是否可以对对象做类似的事情。
例如,如果我有一段这样的代码:
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
希望对您有所帮助。您可以将此代码与您收到的对上一个问题的答案结合起来,一切都会正常运行。