Oop MATLAB中新图形的怪异行为
我创建了一个类管理的GUI,其中定义了以下方法Oop MATLAB中新图形的怪异行为,oop,matlab,user-interface,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(
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\u figure
方法将运行,尽管它不是使用h=figure('CloseRequestFcn',@this.close\u figure)创建的代码>的<代码>制作图形<代码>方法!!!这是第一个奇怪的部分。第二个奇怪的部分是,尽管执行了代码中不需要的部分,但它不应该产生问题,因为命令this.openFigures(this.openFigures==src)=[]代码>实际上保留了这个。openFigures
没有改变,实际上close\u figures
所做的就是delete(src)
,这是可取的。尽管如此,我的程序仍能正常运行。。。在上述情况发生后,我觉得很奇怪
我注意到,如果在命令窗口中点击figure
,然后将其关闭,一切正常,则不会执行close\u figure
方法。只有在打开GUI类创建的.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
现在使用我们的类包装器,让我们创建一个图形,并将其保存到FIG文件:
f = MyFigureClass();
f.make_figure()
f.save_figure(1) %# creates fig01.fig
接下来清除您的工作区清除所有
,并将类定义文件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
编辑2
一种解决方案(如注释中所述)是在保存回调函数之前关闭它。下面是我如何修改上面的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
我只是想指出,其他人可能会面临一个相关的问题。您不应该双击GUI.fig文件来打开GUI。这不是期望的行为,因为永远不会调用打开函数。如果像我们很多人那样在那里有代码,它将不会执行,另一个副作用是句柄变量也不会正确设置
您应该首先在GUIDE中打开它,然后单击run,或者直接运行gui.m文件。这将产生所需的结果,gui将按预期运行。您要打开的FIG文件中到底有什么内容?它是一个指南生成的GUI,还是您保存的一个简单的MATLAB图形?无论哪种方式,创建一个新的(没有什么花哨的只是非常简单的一个),然后再试一次。。。如果问题仍然存在,我怀疑您的安装可能以某种方式被破坏,并建议您reinstall@niels:噢,问题是当从类内部保存图形时,它创建了一个闭包(用于回调函数)。现在在一个新的会话中,如果您试图打开FIG文件,而类定义文件不在MATLAB路径上,它将抛出您提到的错误。@niels:我添加了一些步骤来重现错误。。。显然,现在的解决方案是将类定义和保存的FIG文件保持在一起(并使其在路径上可用)@niels:我添加了一个解决方案,在保存图形之前将回调函数重置为MATLAB的默认值,然后恢复
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