是的,这是预期的行为!变量test
的范围对每个函数都是局部的,所以您不能在一个函数中更改它,并期望更改后的值出现在另一个函数中。
这里有几个选项!例如,您可以使用handles
结构传递“全局”变量。在代码中,你将不得不修改它,像这样:
% --- Executes on button press in stop.
function stop_Callback(hObject, eventdata, handles)
handles.test = 0;
set(handles.display, 'String', num2str(handles.test));
guidata(hObject, handles); % Store the changed handles structure
% --- Executes on button press in start.
function run_Callback(hObject, eventdata, handles)
handles.test = 1;
while handles.test > 0
handles.test = handles.test + 1;
set(handles.display, 'String', num2str(handles.test));
guidata(hObject, handles); % stores the changed handles structure
pause(1);
handles = guidata(hObject); % updates "handles" to see the change!
end
这是一个非常标准的方法,但它有一些缺点:这是超级容易不小心遗漏更新或检索handles
结构。此外,由于这两个功能并行运行,它们容易受到竞争条件的影响。
第二种方法是使用global
语句。它插入容易:
% --- Executes on button press in stop.
function stop_Callback(hObject, eventdata, handles)
global test;
test = 0;
set(handles.display, 'String', num2str(test));
guidata(hObject, handles);
% --- Executes on button press in run.
function run_Callback(hObject, eventdata, handles)
global test;
test = 1;
while test > 0
test = test + 1;
set(handles.display, 'String', num2str(test));
guidata(hObject, handles);
pause(1);
end
然而,这也带有一些缺点:现在变量test
是真正的全球化。它可以在其他脚本,函数或GUI中进行更改,因此您应该选择比test
更独特的名称,并且一般要小心。另外,如果(单例)GUI在不关闭的情况下重新启动,GUI的可视状态,handles
结构的内容以及全局变量的内容可能会变得“不同步”。我被这两次咬伤,所以我不再使用这种方法。
第三种方法包含变量test
应始终链接到GUI文本字段的事实。因此它使用display
字段中的字符串替代变量。从本质上讲,这意味着使用get
,set
,str2double
和num2str
很多:
% --- Executes on button press in stop.
function stop_Callback(hObject, eventdata, handles)
set(handles.display, 'String', num2str(0));
guidata(hObject, handles);
% --- Executes on button press in start.
function run_Callback(hObject, eventdata, handles)
set(handles.display, 'String', num2str(1));
while str2double(get(handles.display, 'String')) > 0
set(handles.display, 'String', ...
num2str(str2double(get(handles.display, 'String')) + 1));
guidata(hObject, handles);
pause(1);
end
这是冗长的,但它是我在这些情况下使用。这是最健壮的解决方案,尤其是在重新启动(单例)GUI时不首先关闭它。
第一种方法按预期工作!我之前在测试中使用过它,但我没有意识到这一行“handles = guidata(hObject);%更新”句柄“以查看更改!”所以它不见了,所以它的行为就像我的请求中的代码。 谢谢! – user3548298
关于第一种和第三种方法,最有效的是什么?我试图为音频制作一个实时处理程序,我需要小心这个问题 – user3548298
我的直觉告诉我,两种方法都非常高效 - 带有'global'声明的方法可能是最快的。在第一种和第三种方法之间,我猜第一种方法更快。但只有测试才能确定。实时音频可能会非常棘手,您可能需要解决更先进的魔法。无论如何,祝你好运! –