Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab-GUI-通过在其他回调中更改变量来修改变量_Matlab_Loops_User Interface_Variables_Global - Fatal编程技术网

Matlab-GUI-通过在其他回调中更改变量来修改变量

Matlab-GUI-通过在其他回调中更改变量来修改变量,matlab,loops,user-interface,variables,global,Matlab,Loops,User Interface,Variables,Global,我想制作一个简单的程序,在按下运行按钮时在循环中显示一个递增的数字,并在循环中按下另一个按钮来更改该值。到目前为止,我使用发现的程序增加了数字并正确显示,但我使用的变量显然是相互独立的,因此每当我将值重置为0时,循环将继续在重置前留下的位置 % --- Executes on button press in stop. function stop_Callback(hObject, eventdata, handles) test = 0; set(handles.display, 'Strin

我想制作一个简单的程序,在按下运行按钮时在循环中显示一个递增的数字,并在循环中按下另一个按钮来更改该值。到目前为止,我使用发现的程序增加了数字并正确显示,但我使用的变量显然是相互独立的,因此每当我将值重置为0时,循环将继续在重置前留下的位置

% --- Executes on button press in stop.
function stop_Callback(hObject, eventdata, handles)
test = 0;
set(handles.display, 'String', num2str(test));
guidata(hObject, handles);

% --- Executes on button press in run.
function run_Callback(hObject, eventdata, handles)
test = 1;
while test > 0
    test = test + 1;
    set(handles.display, 'String', num2str(test));
    guidata(hObject, handles);
    pause(1);
end

知道如何使这个测试变量成为全局变量、如何初始化它以及我应该将它放在文件中的什么位置吗?

是的,这是预期的行为!变量
test
的范围是每个函数的局部范围,因此不能在一个函数中更改它,而期望更改后的值出现在另一个函数中

在这方面有一些选择!例如,可以使用
句柄
结构传递“全局”变量。在您的代码中,您必须对其进行如下修改:

% --- 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
这是一种相当标准的方法,但也有一些缺点:很容易意外地忽略更新或检索
句柄
结构。此外,由于这两个函数并行运行,它们容易受到竞争条件的影响

第二种方法是使用
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的可视状态、
的内容处理
结构,以及全局变量的内容可能会变得“不同步”。我被咬了两次,所以我不再使用这种方法了

第三种方法包括变量
test
应始终链接到GUI文本字段。因此,它使用
显示
字段中的字符串代替变量。本质上,这意味着大量使用
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而重新启动GUI时。

您可以将变量声明为全局变量。这就行了

% --- 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

如果您的项目很小,并且可以放在单个M文件中,那么您可以使用

如果您正在使用guide制作GUI,那么您可以通过以下方式最轻松地做到这一点:(确保首先保存GUI编辑自动生成的m文件的副本)

  • 打开m文件
  • 如果函数未以关键字
    end
    结束,则将其添加到定义的所有函数中,第一个函数除外(其名称在m文件中)
  • 在m文件的最底部添加一个额外的
    end

  • 在此之后,您在top函数中定义的任何变量都将可用于较低的函数(嵌套的函数,它们也是回调函数)。如果变量在多个函数中具有作用域,则标准Matlab编辑器将在此颜色后以不同方式突出显示变量

    第一种方法按预期工作!实际上,我在前面的测试中使用了它,但我不知道有一行“handles=guidata(hObject);%更新了“handles”以查看更改!”因此它丢失了,所以它的行为与我请求中的代码类似。谢谢关于第一种和第三种方法,最有效的方法是什么?我正在尝试为音频制作一个实时处理程序,我需要小心我的直觉告诉我这两种方法都不是非常有效的-使用
    global
    语句的方法可能是最快的。在第一种和第三种方法之间,我想第一种方法更快。但只有测试才能确定。实时音频可能很棘手,您可能需要解决更高级的魔术。无论如何,祝你好运!