Matlab 实时更新回调函数内的值[这些值来自外部函数(另一个.m文件)]
我有一个外部函数,比如“external_func”(separate.m文件) 在这个函数中调用一个while循环,这个while循环更新一个名为“update_prog”的变量 现在,我将使用Matlab 实时更新回调函数内的值[这些值来自外部函数(另一个.m文件)],matlab,matlab-guide,Matlab,Matlab Guide,我有一个外部函数,比如“external_func”(separate.m文件) 在这个函数中调用一个while循环,这个while循环更新一个名为“update_prog”的变量 现在,我将使用 assignin('base', 'update_prog', update_prog); % passing to workspace 我正在做这个 “update_prog”作为全局变量,并将其调用到GUIDE.m文件中 function pb1_Callback(hObject, eventd
assignin('base', 'update_prog', update_prog); % passing to workspace
我正在做这个
“update_prog”作为全局变量,并将其调用到GUIDE.m文件中
function pb1_Callback(hObject, eventdata, handles)
global update_prog
% hObject handle to pb1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% else
% set(handles.pb1,'enable','on');
% end
% update_prog first value prints, but it wont updates as the loop in external_func goes on.
drawnow;
set(handles.slider1,'Value',update_prog)
external_func;
在GUIDE.m文件中,我可以得到这个值
“update_prog”但它无法跟上while循环。我用了“drawnow”,但没用
当“外部函数”中的while循环经过多次迭代时,如何优化该值“update_prog”。[注意:更新的值在GUIDE的回调函数中,但除非有回调,否则回调函数不会更新“update_prog”],因此如何在回调函数中实现此实时更新
[注意:在我的例子中,通过函数输入传递变量是不可能的,因此我正在寻找替代方法]
请考虑这个链接,它有一个例子
我在这里做的是
集合(handles.slider,'Value',variable)
这样我就不能移动滑块了
为什么?
update\u prog
变量不是全局变量(必须在要使用它的每个工作区中将其定义为全局变量)
既然您使用globals(有很多更好的方法可以做到这一点,但这不是您的问题),为什么不在external\u func
函数中将update\u prog
变量定义为全局变量(替换assign调用)
编辑在您的外部函数
函数中添加drawnow。这样,当您单击按钮时,它将更新
编辑3
我想我知道你想做什么,试试这个例子,看看它是否做了你想做的事情-更新以显示如何在代码中找到滑块对象并在循环中更新:
function mygui
% create a figure
f = figure;
% create a uicontrol slider - note that I give it a tag.
uicontrol ( 'style', 'slider', 'Position', [0 200 200 40], 'tag', 'MYSLIDER', 'backgroundcolor', 'white', 'parent', f );
% create a push button which we can press to update
uicontrol ( 'string', 'Press 2 start', 'callback', @(a,b)myLoop(), 'Position', [0 0 200 50] )
end
% This replicates your "external_func" function.
function myLoop()
% since you cant pass in any var -> you need to find the slider object
% you can do this by using findobj and search for the tag of the item
uic = findobj ( 0, 'tag', 'MYSLIDER' );
% find the figure handle (only needed for this demo)
f = ancestor ( uic, 'figure' );
% initialise the value which will be used to update the slider
count = 0;
% create your loop
while ishandle(f)
% incrememt the count variable -> this will end up on the slider value
count = count + 1e-5;
% reset count if > 1 -> so the slider cant go out of range.
if count >= 1
count = 0;
end
set ( uic, 'Value', count );
% initiate a drawnow -> this allows matlab to process GUI events
drawnow();
end
end
这样做的缺点是在循环->中插入drawnow-,这可能会稍微降低速度
如果这不能解决你的问题,你需要更好地解释你想做什么。。。(在我看来)我不建议用中间工作区(外部->基本工作区->GUI)分三步传递变量。我建议直接传递变量(外部->GUI) 每个Matlab图形都提供了一个空间来存储任何类型的变量(应用程序数据)。我建议阅读这篇文章并阅读3个功能的文档:
global
声明
下面是一个简单gui的示例。gui在其用户空间中声明变量(使用
setappdata
),然后使用计时器定期读取此变量(使用getappdata
)。外部函数执行您希望它执行的任何操作(示例中只是一个随机数),然后使用相同的
setappdata
更新变量。唯一需要的是主GUI图形的句柄,因此在本例中,我将其作为外部函数的输入
GUI还有两个按钮用于启动和停止更新
主要示例GUI“theGui.m”的代码为:
function h = theGui
%// basic GUI with 2 buttons and 1 slider
h.fig = figure('Position',[433 434 500 100],'Menubar','none','CloseRequestFcn',@my_closefcn) ;
h.sld = uicontrol('Style','Slider','Position',[20 20 460 20]) ;
h.btnStart = uicontrol('Style','pushbutton','String','Start updating','Callback',@btnStart_callback,'Position',[20 50 200 30]);
h.btnStop = uicontrol('Style','pushbutton','String','Stop updating','Callback',@btnStop_callback,'Position',[280 50 200 30],'Max',1,'Min',0);
%// Define the timer
h.t = timer ;
h.t.Period = 0.1 ; %// 0.1s refresh interval
h.t.TimerFcn = {@timer_callback,h.fig} ;
h.t.ExecutionMode = 'fixedSpacing' ;
%// initialise the variable to update in the GUI appdata
update_prog = 0 ;
setappdata( h.fig , 'update_prog' , update_prog ) ;
%// save handles
guidata( h.fig , h );
function btnStart_callback(hobj,~)
h = guidata( hobj ) ; %// retrieve handles
if strcmp('off',h.t.Running) %// Start timer (only if not already running)
start(h.t)
end
function btnStop_callback(hobj,~)
h = guidata( hobj ) ; %// retrieve handles
stop(h.t) %// Stop timer
function timer_callback(~,~,hfig)
update_prog = getappdata( hfig , 'update_prog' ) ; %// retrieve the 'update_prog' variable value
h = guidata( hfig ) ; %// retrieve handles
set(h.sld , 'Value' , update_prog) ; %// update the slider object with the retrieved value
function my_closefcn(hobj,~)
%// this function is only to clean up when the GUI will be closed.
%// It is recommended to delete the timer manually
h = guidata( hobj ) ; %// retrieve handles
stop(h.t) %// Stop timer (in case it is still running)
delete(h.t) ; %// delete the timer
delete(h.fig) ; %// destroy the figure
以及external_func.m
function external_func( guiMainFigureHandle )
%// This function will only generate random numbers and push them into the
%// variable 'update_prog' contained in the GUI appdata.
%// This is why this function NEEDS the handle of the gui to be able to
%// access the Application Data space of the gui.
for k = 1:100
randomValue = rand(1) ; %// generate a random value
hfig = ancestor( guiMainFigureHandle , 'figure' ) ; %// make sure the handle provided is the top level figure
setappdata( hfig , 'update_prog' , randomValue) ; %// update the variable value
pause(0.1) ;
end
编辑: 我把它放在edit中,而不是更改上面的代码,因为如果不需要的话,我不建议弄乱
root
对象。但在你的情况下,这可以解决你的问题
如果您的外部函数无法访问GUI,则它始终可以更新一部分内存,该内存可用于给定Matlab会话中运行的所有程序,即根对象。它的句柄是保留的,并且对于任何程序都是相同的:0
(尽管自v2014b以来,有另一种方法调用它:,但对于所有Matlab来说,它始终是相同的句柄)
因此,在上面的示例中,在gui.m中使用:
setappdata( 0 , 'update_prog' , update_prog ) ;
在主例程中,然后在子函数函数timer\u回调(~,~,hfig)
中,使用:
update_prog = getappdata( 0 , 'update_prog' ) ; %// retrieve the 'update_prog' variable
并且您的函数external_func()
不需要任何额外的参数,更新只需要一行:
setappdata( 0 , 'update_prog' , update_prog) ; %// update the variable value
他需要的是协同例程,但不能在MATLAB中实现。有一个回调会中断已经执行的函数,并且回调会对共享变量进行更改,这样当回调返回时,更改将影响中断函数中的下一次迭代。@matlabgui这是多余的。我把它移走了。谢谢但是没有什么变化,一切都是一样的。[工作区分配是正在进行的一件额外的事情]。它实际上没有对行为进行任何更改。@CST Link…是的,这正是正在发生的事情。回调完成后,我可以看到值更新。如果我只是中断循环(只是为了检查),我可以看到回调中值的进度。@statisticalbeginner我相信我们已经讨论过了:您不能从GUI启动外部函数,因为您将无法通过回调中断它(回调将被丢弃,或者