我正在为现有脚本开发GUI,该脚本需要在基本工作区中使用一些Struct Value。GUI应将用户值传输到基本工作区,然后立即启动脚本并关闭自身。这听起来很简单,值与assignin和evalin一致,但我花了好几天的时间来处理这个问题,如果脚本随后自己创建值,我会得到消息:
尝试将var_name添加到静态工作区。有关详细信息,请参阅MATLAB编程,变量赋值限制
问题出在哪里?GUI关闭,脚本应无限制地使用基本工作区。如何做到这一点?脚本是不可触摸的(不是我的),它希望变量在基本工作区中,所以GUI应该将值传输到工作区,而不是其他任何东西。不需要静态工作区。工作区应不受任何限制。很快:我想删除"静态工作区"中的"静态"
MATLAB文档指定:
如果您试图将变量动态添加到匿名函数、嵌套函数或包含嵌套函数的函数。
因此,您的问题很可能是直接从GUI中某个按钮的匿名回调中调用脚本造成的(没有详细信息,我只能猜测)。如果是这种情况,那么将其封装到另一个函数中,这样您就可以将脚本创建的变量与anon函数工作区隔离开来。
将包装器函数设计为接受要传递给脚本的变量作为参数,这样脚本就有了它所需要的。此外,请确保您没有在包装器中嵌套函数,因为您会遇到同样的问题。
注意:与您预期的相反,函数调用的脚本不会在Base工作区中创建其变量,而是在函数的工作区中。只有当从另一个脚本调用时,它才会使用基本工作区来创建变量。
示例:假设脚本"his_script.m"要求变量invar1
和invar2
已经在其可访问的工作空间中;脚本的输出(即创建的变量)是变量outvar3
和outvar4
:
% his_script.m
outvar3 = invar1 + invar2;
outvar4 = invar1 - invar2;
因为没有assignin
和evalin
,我们可以将其封装为函数my_wrapper.m
:
% my_wrapper.m
function [outvar3, outvar4] = my_wrapper(invar1, invar2)
% Pre-create the outputs if the script cannot promise with
% the hand on the Holy Book of Execution Paths that it will
% create all the output variables.
outvar3 = [];
outvar4 = [];
% Call the script
his_script;
end
函数参数将作为脚本的输入,函数的返回值将是脚本的输出。
现在,您可以在按钮的匿名回调中使用对包装器函数的调用,例如:
% initialization function of your GUI
% ...
set(action_button_handle, 'Callback', action_button_callback);
% ...
% somewhere deep in your GUI code, nested function for
% manipulating the script
function action_button_callback(hObject, callbackdata)
[out1, out2] = my_wrapper(5,3);
display(out1);
display(out2);
end
% ...
我希望这个想法现在更清楚了。请让我知道它是如何为你工作的。
进一步评论:脚本和函数之间的主要区别之一是脚本没有自己的工作区,而函数有。脚本使用调用它们的上下文的工作区。
这意味着您的目标"GUI应该将值传输到工作区,而不是其他任何东西"是误导性的,因为您不知道脚本的工作区在哪里,除非您首先调用它。
如果真的希望GUI在基本工作区中编写,您可以让它这样做,但您应该从控制台窗口手动调用脚本,因为控制台窗口的上下文是基本工作区。或者试着使用evalin('base', 'script_name;');
,但你需要测试(到目前为止,我抵制住了使用这样的东西的诱惑——正是因为它很容易出错,我不想被诅咒)。