将数据存储在GUIDE中的嵌套函数中,Matlab

时间:2016-10-12 12:52:17

标签: matlab user-interface matlab-figure

我正在尝试在matlab中创建一个简单的gui并遇到一些问题。这个简化程序的主要思想是我有一个滑块,它决定了正弦波的频率。两个图显示了结果信号。高分辨率为44100 Hz,低分辨率为100 Hz。另一个滑块确定绘制信号的长度(也以Hz为单位测量)。原始程序有更多的滑块可以添加更多的频率,但由于我认为它不重要,我试图将其缩小回来以解决这个问题。结果代码仍然非常大,对不起。

我的问题是它并不总是更新,我收到错误消息。我尝试将所有东西存放在手柄中,因为我认为这就是你应该如何做到的。 handles.lowresx包含低res时间标度,handles.highresx包含高res时间标度。然后在函数calcandplot(handles)中创建临时lowresy和highresy。每次移动时间间隔滑块时,都会从滑块移动回调中调用函数recalcx(hObject,newhz,handles),并计算新的lowresx和lowresy。它然后存储在guidata(hObject,handle)中(我希望),这些用于计算新的lowresy和highresy用于绘图。它似乎没有存储。

当它是回调函数中的嵌套函数时,我不确定如何保存数据。我应该在调用堆栈中一直调用guidata(hObject,handle),这意味着我必须将hObject作为参数传递给每个函数?或者只在最内在的功能?我已经尝试了两个,没有一个真的有用。如果我以后不需要它们,或者我是否应该将它们保存在句柄中,以使一切正常工作,那么仅仅计算lowresy和highresy并绘制它们就足够了吗?或者它是否足够了?

在调用set(handles.intervaltext,'String',num2str(val))之后是否必须调用guidata(句柄)或者是否自行更新?

我对手柄有疑问。我理解它的方式是每次调用函数时都会创建并传递一个副本。这是否会对您可以保存哪些大数据结构产生某种限制?如果在每个gui组件上调用某种事件时会创建一个副本(鼠标悬停,按下按键等),我当然可以看到事情会变得迟缓。有关如何处理此问题的任何提示?

错误讯息:

Reference to non-existent field 'lowresx'.

Error in gui>calcandplot (line 85)
lowresy = wave(handles.lowresx, handles.freq1);

Error in gui>intervalslider_Callback (line 106)
calcandplot(handles);

代码:

function varargout = gui(varargin)
% GUI MATLAB code for gui.fig
%      GUI, by itself, creates a new GUI or raises the existing
%      singleton*.
%
%      H = GUI returns the handle to a new GUI or the handle to
%      the existing singleton*.
%
%      GUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in GUI.M with the given input arguments.
%
%      GUI('Property','Value',...) creates a new GUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before gui_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to gui_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help gui

% Last Modified by GUIDE v2.5 12-Oct-2016 14:18:38

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @gui_OpeningFcn, ...
                   'gui_OutputFcn',  @gui_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before gui is made visible.
function gui_OpeningFcn(hObject, eventdata, handles, varargin)
handles.freq1 = 0;
handles.lowsr = 1000;
handles.sr = 44100;
handles.lenhz = 220;
recalcx(hObject, handles.lenhz, handles);
'recalculated'

% Choose default command line output for gui
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes gui wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = gui_OutputFcn(hObject, eventdata, handles) 
varargout{1} = handles.output;

% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
val = get(hObject,'Value');
handles.freq1 = val;
guidata(hObject, handles);
set(handles.text1, 'String', num2str(val));
calcandplot(handles);

% --- Executes during object creation, after setting all properties.
function slider1_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function calcandplot(handles)
lowresy = wave(handles.lowresx, handles.freq1);
highresy = wave(handles.highresx, handles.freq1);
axes(handles.axes1);
plot(handles.lowresx,lowresy, 'o');
axes(handles.axes2);
plot(handles.highresx,highresy, 'o');

function y = wave(x, freq1)
% x in sec
y = sin(x*freq1);

% --- Executes on slider movement.
function intervalslider_Callback(hObject, eventdata, handles)
val = get(hObject,'Value');
recalcx(hObject, val, handles);

strcat('val is now ', num2str(val))
strcat('handles.lenhz is now', num2str(handles.lenhz))
guidata(hObject, handles);
set(handles.intervaltext, 'String', num2str(val));
handles
calcandplot(handles);

% --- Executes during object creation, after setting all properties.
function intervalslider_CreateFcn(hObject, eventdata, handles)
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

function recalcx(hObject, newhz, handles)
handles.lenhz = newhz;
handles.lowresx = (0:1/handles.lowsr:(2*pi)/handles.lenhz)';
handles.highresx = (0:1/handles.sr:(2*pi)/handles.lenhz)';
strcat('inside handles is', num2str(handles.lenhz))
guidata(hObject, handles);
strcat('inside handles again is', num2str(handles.lenhz))

1 个答案:

答案 0 :(得分:1)

问题是在recalcx内,您要通过添加字段handles来修改lowresx。您(正确地)使用guidata(hObject, handles)将其保存到guidata。

问题是在调用函数(gui_OpeningFcn)中,然后将修改后的不同的 handles结构保存到guidata中handles内的recalcx结构不会传播回调用函数。

这个handles结构没有那些字段然后在你的GUI周围传递并导致你看到的错误。

如何解决此问题的一个选择是让recalcx返回修改后的handles结构

function handles = recalcx(hObject, newhz, handles)
    handles.lenhz = newhz;
    handles.lowresx = (0:1/handles.lowsr:(2*pi)/handles.lenhz)';
    handles.highresx = (0:1/handles.sr:(2*pi)/handles.lenhz)';
    strcat('inside handles is', num2str(handles.lenhz))
    guidata(hObject, handles);
    strcat('inside handles again is', num2str(handles.lenhz))
end

然后调用函数可以有更新版本

function gui_OpeningFcn(hObject, eventdata, handles, varargin)
    handles.freq1 = 0;
    handles.lowsr = 1000;
    handles.sr = 44100;
    handles.lenhz = 220;
    handles = recalcx(hObject, handles.lenhz, handles);

    % Choose default command line output for gui
    handles.output = hObject;

    % Update handles structure
    guidata(hObject, handles);