为什么guihandles不能在这种情况下工作?

时间:2014-09-29 19:12:47

标签: matlab user-interface global-variables matlab-guide programmatically-created

我正在开发一个大的GUI,它的基本结构非常简单,可以简单地简化为两个互连的控件(每个控件更新另一个控件的值):一个滑块和一个编辑框。他们共享的价值用于制作情节。 如果运行以下代码,则会发现只能更改一次值(通过移动幻灯片或编辑框)。第二次,它会抛出一个错误。主要问题是:为什么?如何使用GUIHANDLES INSTEAD?

function GuiHandleShare1

handles.figure=figure;

handles.edit=uicontrol('Style','Edit',...
                       'Position',[5  5 50 20],...
                       'Callback',@edit_callback,...
                       'Tag','edit');
handles.slider=uicontrol('Style','Slider',...
                         'Position',[55 5 500 20],...
                         'Callback',@slider_callback,...
                         'Tag','slider');
handles.axes=axes('OuterPosition',[0.1 0.1 0.8 0.8],...
                  'Tag','axes');

function plotter
handles=guihandles;
plot(handles.axes,[0 1],[0 str2num(get(handles.edit,'String'))])

function edit_callback(h,eventdata)
handles=guihandles;
set(handles.slider,'Value',str2num(get(handles.edit,'String')));
plotter

function slider_callback(h,eventdata)
handles=guihandles;
set(handles.edit,'string',num2str(get(handles.slider,'Value')));
plotter

我试图通过挖掘guihandles的代码找到答案,但就像guidata一样,它是getappdata,setappdata等的包装器,其来源不可用(Matlab R2008b)。

我已经知道这种GUI的其他解决方案: 1-而不是使用guihandles,guidata或其他类似的东西,我使用全局变量。 2-使用嵌套函数。

在我正在处理的情况下,嵌套函数不是一个选项,因为这会使主函数工作区成为静态工作区。这不是我想要的,因为我必须在应用程序中管理变量。 我最终使用全局变量:我在每个需要它们的函数中声明句柄是全局的,并且它工作正常。这有什么不利吗?我的意思是,如果我们可以使用全局变量,为什么Matlab会提出像guihandles,guidata等命令?

2 个答案:

答案 0 :(得分:3)

您必须使用此属性/值对:

'NextPlot' ,'ReplaceChildren'

在最开始的轴定义中,否则GUI在第一个绘图之后创建一个新图形,并且与开头的轴相关联的标记不再有效。实际上如果你输入

get(handles.axes)

创建它之后,您将看到此属性设置为'replace',它将替换整个轴而不是其子轴。因此代码看起来像这样:

handles.axes=axes('OuterPosition',[0.1 0.1 0.8 0.8],...
                  'Tag','axes','NextPlot' ,'ReplaceChildren');

作为全局变量的变通方法,您还可以使用findobj来检测轴,然后在其中绘图:

function plotter

hAx = findobj('Type','axes')
handles=guihandles;
plot([0 1],[0 str2num(get(handles.edit,'String'))],'parent',hAx);

但如果您有多个轴,则不太方便。

据我所知,GUI中的全局变量使代码更容易实现,但我知道的一个警告是,如果您计划从GUI部署独立应用程序,那么在编译过程中会出现大量错误将不得不摆脱他们。

无论如何使用上面的代码对我来说很好。希望有所帮助!

答案 1 :(得分:3)

我认为你误解了函数guihandles(),它给出了图中真实句柄的列表,与guidata()不同。实际上,尝试将handle.axes重命名为handles.axes1,并且您将在第一次回调时看到它失败。

此代码使用guidata()来保存和检索数据(行尾的注释)。

function GuiHandleShare1

handles.figure=figure;

handles.edit=uicontrol('Style','Edit',...
                       'Position',[5  5 50 20],...
                       'Callback',@edit_callback,...
                       'Tag','edit');
handles.slider=uicontrol('Style','Slider',...
                         'Position',[55 5 500 20],...
                         'Callback',@slider_callback,...
                         'Tag','slider');
handles.axes1=axes('OuterPosition',[0.1 0.1 0.8 0.8],...
                  'Tag','axes');
guidata(handles.figure, handles); % save handles to GUIDATA

function plotter
handles=guidata(gcf); % retrieve handles from GUIDATA
plot(handles.axes1,[0 1],[0 str2num(get(handles.edit,'String'))])

function edit_callback(h,eventdata)
handles=guidata(gcf);
set(handles.slider,'Value',str2num(get(handles.edit,'String')));
plotter

function slider_callback(h,eventdata)
handles=guidata(gcf);
set(handles.edit,'string',num2str(get(handles.slider,'Value')));
plotter