【问题标题】:Matlab figure 'age'Matlab 图“年龄”
【发布时间】:2018-07-13 20:22:51
【问题描述】:

这里有一个问题要问“Matlab 中记录较少的部分的专家”:是否有(未记录的?)方法来确定一个图的开放时间(即图的“年龄”)?

figure; spy;
myfig=gcf;
age=get_age() %shoud output age of figure in some format

【问题讨论】:

    标签: matlab undocumented-behavior


    【解决方案1】:

    您可以使用以下机制:

    首先,如下创建一个小 Matlab 函数,将 CreationTime 属性附加到图形:

    function setCreationTime(hFig,varargin)
       hProp = addprop(hFig,'CreationTime');
       hFig.CreationTime = now;
       hProp.SetAccess = 'private'; %make property read-only after setting its initial value
    
       hProp = addprop(hFig,'Age');
       hProp.GetMethod = @(h,e) etime(datevec(hFig.CreationTime), clock); %compute on-the-fly
       hProp.SetAccess = 'private'; %make property read-only
    end
    

    现在将此函数指定为从现在开始所有新人物的默认CreateFcn回调函数:

    set(0,'DefaultFigureCreateFcn',@setCreationTime)
    

    就是这样 - 你完成了!

    例如:

    >> newFig = figure;
    >> newFig.CreationTime
    ans =
          737096.613706748
    
    >> ageInDays = now - newFig.CreationTime
    ageInDays = 
           0.01625078368466347
    >> ageDuration = duration(ageInDays*24,0,0)
    ageDuration = 
      duration
       00:23:24
    >> ageString = datestr(ageInDays, 'HH:MM:SS.FFF')
    ageString = 
        '00:23:24.068'
    
    >> ageInSecs = newFig.Age
    ageInSecs =
        1404.067710354923808
    

    【讨论】:

    • picky picky...我在答案中添加了额外的步骤
    • 请原谅我的挑剔——我不知道 CreateFcn,那是天才。如果您将 setCreationTime 更改为包含 addprop(hFig,'age'); hFig.age = @() etime((hFig.CreationTime),(clock)); 然后使用 feval(newFig.age) 您将获得以秒为单位的时间!
    • 我通过添加 Age 计算属性更新了答案。使用属性的 GetMethod 可以避免使用 feval。另请注意,在您的评论中,您忘记了 datevec()...
    【解决方案2】:

    据我所知,图形对象不会公开此类信息。甚至在其未记录的底层Java 类中也没有。但我有一个想法可能是解决这个问题的好方法。

    使用figure function 的以下重载:

    figure(n) 查找 Number 属性等于 n 的图形, 并使其成为当前数字。如果没有数字存在 属性值,MATLAB® 创建一个新图窗并设置它的 Number n 的属性。

    为了为每个现有图形分配一个“唯一标识符”,并将这些标识符与代表创建时间的datenum 值相关联:

    % Initialize the lookup table somewhere in your code:
    lookup_table = zeros(0,2);
    % Together with a variable that stores the next unique identifier to be assigned:
    next_id = 1;
    
    % When you need to instantiate a new figure...
        % 1) Retrieve the current datetime:
        cdate = now();
        % 2) Update the lookup table:
        lookup_table = [lookup_table; next_id cdate];
        % 3) Initialize the new figure:
        figure(next_id);
        % 4) Increment the next unique identifier:
        next_id = next_id + 1;
    

    查找表的每一行都将包含一个唯一的图形标识符及其各自的创建日期。

    其他一切都很容易处理。当你想查询一个数字正常运行时间...在查找表中找到它的唯一标识符并将当前时间(使用now() 命令获得)减去创建时间。我建议您为您创建的每个图形定义一个CloseRequestFcn 句柄,这样当图形关闭时,您可以更新lookup_table 并将其删除。您分配给特定图形的标识符可以使用其Number 属性进行检索。这是一个完整的工作实现:

    global lookup_table;
    global next_id;
    
    lookup_table = zeros(0,2);
    next_id = 1;
    
    f1 = create_figure();
    f2 = create_figure();
    
    pause(10);
    
    f1_ut = get_figure_uptime(f1)
    f2_ut = get_figure_uptime(f2)
    
    function f = create_figure()
        global lookup_table;
        global next_id;
    
        cdate = now();
    
        f = figure(next_id);
        f.CloseRequestFcn = @update_lookup_table; 
    
        lookup_table = [lookup_table; next_id cdate];
        next_id = next_id + 1;
    end
    
    function ut = get_figure_uptime(f)
        global lookup_table;
    
        tn = now();
        tc = lookup_table(lookup_table(:,1) == f.Number,2);
    
        if (isempty(tc))
            ut = -1;
        else
            ut = etime(datevec(tn),datevec(tc));
        end
    end
    
    function update_lookup_table(f,~)
        global lookup_table;
        lookup_table(lookup_table(:,1) == f.Number,:) = [];
    
        delete(f);
    end
    

    或者,正如您在评论中建议的那样,您可以为您创建的每个图形添加一个属性,其中可以存储其创建时间。它更加直接,并且无需处理查找表。为此,只需使用addprop functon,如下所示:

    cdate = now();
    
    f = figure();
    addprop(f,'CreationTime');
    f.CreationTime = cdate;
    

    【讨论】:

    • 我喜欢这个主意;我想我宁愿将创建的实际时间存储在图形对象中。作为一个附带问题:这可以轻松完成吗?我注意到myfig.time=now(); 抛出一个错误,addproperty(myfig,'time'); 也是如此
    • 那么你必须使用addprop(myfig,'time');。它有效。
    • 仅供参考:我可能还会为名为@9​​87654335@ 的图形添加一个匿名函数(myfig.age(myfig.CreationTime) 从图形中轻松“挖掘”年龄。如果有任何方法可以在匿名函数中使用 'self' 或类似的东西来自引用 myfig 结构,那将是最佳选择,但这已经很酷了!
    【解决方案3】:

    参考这个link 您的问题的答案可能是这段代码(这将适用于 MATLAB R2014b 及更高版本)。我用 R2015a 测试过。

    figure; spy;
    my_fig=groot;
    cnt = 0;
    pause(0.05)
    while ~isempty(my_fig.Children)
        cnt=cnt+1
        pause(0.01)
    end
    

    这里的cnt值将与时间成正比,窗口在关闭之前存在。 注意:

    1. 可以减少 pause 的参数值,在计算时间时,要考虑暂停时间
    2. 可以使用系统时钟时间代替计数器方法的cnt变量。

    【讨论】:

      猜你喜欢
      • 2012-03-26
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 2023-01-29
      • 1970-01-01
      • 2022-11-03
      • 2019-10-31
      相关资源
      最近更新 更多