Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.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 实时更新回调函数内的值[这些值来自外部函数(另一个.m文件)]_Matlab_Matlab Guide - Fatal编程技术网

Matlab 实时更新回调函数内的值[这些值来自外部函数(另一个.m文件)]

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

我有一个外部函数,比如“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, 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”],因此如何在回调函数中实现此实时更新

[注意:在我的例子中,通过函数输入传递变量是不可能的,因此我正在寻找替代方法]

请考虑这个链接,它有一个例子

我在这里做的是

  • 将变量(在externel函数的while循环中更新)传递到GUI
  • 我将使用此变量在进度条(滑块)上显示进度
  • 有什么问题? 1.GUI回调中的变量(Consdier I将按下按钮,然后它将使用while循环调用函数)将更新的值放入
    集合(handles.slider,'Value',variable)

    这样我就不能移动滑块了

    为什么?

  • Callback只在我按下按钮时更新变量,接下来所有变量更新都不会更新,因此进度条/滑块不会移动
  • 我“怀疑”基本工作区中的
    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启动外部函数,因为您将无法通过回调中断它(回调将被丢弃,或者