MATLAB中新数字的奇怪行为

时间:2012-06-02 19:39:59

标签: oop matlab user-interface

我创建了一个类管理的GUI,其中定义了以下方法

function h = make_figure(this)
    h = figure('CloseRequestFcn',@this.close_figure);
    this.openFigures(end+1) = h;
end

function close_figure(this, src, event)
    this.openFigures(this.openFigures == src) = [];
    delete(src);
end

在GUI maney的整个生命周期中,借助上述方法创建和关闭数字。现在奇怪的部分......

如果我在MATLAB的“当前文件夹”窗口中双击图形文件,例如(myfigure.fig),然后尝试关闭它(当GUI仍处于活动状态时),则GUI类的close_figure方法运行虽然它不是用h = figure('CloseRequestFcn',@this.close_figure); make_figure方法创建的!这是第一个奇怪的部分。第二个奇怪的部分是,尽管执行了代码的无意义部分,但它不应该产生问题,因为命令this.openFigures(this.openFigures == src) = [];实际上使this.openFigures保持不变,而close_figure实际上所做的就是delete(src)这是可取的。尽管如此,我的程序在上述情况发生后表现得很奇怪。

我注意到如果我在命令窗口中点击figure然后关闭它,一切正常,close_figure方法就不会执行了。只有在打开由GUI类创建的.fig文件时,问题才会显现出来。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

我刚试过你描述的场景,我没有看到任何奇怪的行为;创建类的实例,用它来制作图形,然后从“当前文件夹”文件浏览器中打开一个FIG文件,然后将其关闭..

这是我使用的类定义:

classdef MyFigureClass < handle
    properties
        openFigures = [];
    end

    methods
        function h = make_figure(obj)
            h = figure('CloseRequestFcn',@(src,evt) close_figure(obj,src,evt));
            obj.openFigures(end+1) = h;
        end

        function close_figure(obj, src, evt)
            obj.openFigures(obj.openFigures == src) = [];
            delete(src);
        end

    end
end

(在Windows XP 32位上测试R2012a。)


修改

好的我想我知道问题所在。这是重现的步骤。首先将以下方法添加到上面的类中:

function save_figure(obj, idx)
    saveas(obj.openFigures(idx), sprintf('fig%02d.fig',idx))
end

现在使用我们的类包装器,让我们创建一个数字,并将其保存到FIG file:

f = MyFigureClass();
f.make_figure()
f.save_figure(1)       %# creates fig01.fig

接下来清除工作区clear all,并将类定义文件MyFigureClass.m移动到其他文件夹(不在路径上)。现在尝试加载保存的数字hgload fig01.fig,它将抛出错误:

Warning: Cannot load an object of class 'MyFigureClass':
Its class cannot be found. 
> In C:\Program Files\MATLAB\R2012a\toolbox\matlab\graphics\hgload.p>localLoadFile at 167
  In C:\Program Files\MATLAB\R2012a\toolbox\matlab\graphics\hgload.p>hgload at 59
  In openfig at 72
  In open at 159
  In uiopen at 196 

您必须发出以下命令才能强制关闭它:

close all force

EDIT2

一个解决方案(如评论中所述)是reset数字关闭回调函数,在保存之前。以下是我修改上述save_figure函数的方法:

function save_figure(obj, idx)
    %# backup callback function
    fcn = get(obj.openFigures(idx),'CloseRequestFcn');

    %# set default callback function
    set(obj.openFigures(idx),'CloseRequestFcn','closereq')

    %# save figure
    saveas(obj.openFigures(idx), sprintf('fig%02d.fig',idx))

    %# restore callback function
    set(obj.openFigures(idx),'CloseRequestFcn',fcn)
end

答案 1 :(得分:0)

我只想指出其他人可能面临的问题。您不应通过双击gui.fig文件来打开GUI。这不是理想的行为,因为永远不会调用您的打开函数。如果我们有很多人没有执行代码,那么另一个副作用是handle变量也不会被正确设置。

你应该做的是首先在GUIDE中打开然后单击运行,或直接运行gui.m文件。这将产生预期的结果,并且gui将按预期运行。