使用GUIDE的Matlab GUI:想要动态更新图形

时间:2012-01-05 23:45:37

标签: matlab matlab-guide

我编写了一个Matlab脚本,该脚本使用实时中的虚拟COMM端口读取数据。我在mfile中完成了大量的信号处理。

接下来,我觉得需要一个紧凑的GUI,将信息显示为摘要。

我最近才开始挖掘和阅读更多Matlab的内置GUI工具GUIDE。我已经按照了一些教程,成功地将我的图表显示在我的GUI 按下按钮之后。

但是,我希望 GUI能够实时更新。我的数据向量不断更新(从COMM端口读取数据)。我希望GUI能够使用较新的数据保持更新图表,而不是依靠按下按钮进行更新。有人可以指出我正确的方向进行背景更新吗?

以下是目前GUI的相关代码:

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global data
global time

% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);

编辑更改代码:

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%Setting it to display something when it ends
% t = timer('TimerFcn', 'timerOn=false; disp(''Updating GUI!'')',... 
t = timer(... 
            'TasksToExecute', 10, ... % Number of times to run the timer object
            'Period', 3, ...                
            'TimerFcn', GUIUpdate()); 

%Starting the timer
start(t)

function GUIUpdate()
global data
global time
%Parameters below axes
    global min
    global max 
      % Time domain plot
    axes(handles.timeDomainPlot);
    cla;
    plot (time, data);
    %Other parameters:
    set(handles.mean, 'String', mean);
    set(handles.max, 'String', max);

我得到的错误是:

??? Error using ==> GUI_Learning>GUIUpdate
Too many output arguments.

Error in ==>
@(hObject,eventdata)GUI_Learning('pushbutton1_Callback',hObject,eventdata,guidata(hObject))


??? Error while evaluating uicontrol Callback

4 个答案:

答案 0 :(得分:10)

以下是使用带有timerFcn回调的计时器的示例。我用一个轴和一个按钮做了一个简单的GUI。

在打开功能中,我初始化绘图并创建计时器。在开始按钮回调中,我启动计时器并开始操作数据。定时器函数回调只是通过其句柄更新行的y数据。下面是GUI的M文件中的相关函数(剪切的init部分和输出fcn。

function testTimer_OpeningFcn(hObject, eventdata, handles, varargin)
global y x
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
handles.plot = plot(handles.axes1,x,y);
handles.timer = timer('ExecutionMode','fixedRate',...
                    'Period', 0.5,...
                    'TimerFcn', {@GUIUpdate,handles});
handles.output = hObject;
guidata(hObject, handles);

% --- Executes on button press in startButton.
function startButton_Callback(hObject, eventdata, handles)
global y x
start(handles.timer)
for i =1:30
   y = sin(x+i/10); 
   pause(1) 
end

function GUIUpdate(obj,event,handles)
global y 
set(handles.plot,'ydata',y);

您可能需要一个“停止”按钮来停止计时器,具体取决于GUI的结构以及数据的更新方式。

编辑:基本处理信息其中一些非常基础,你可能已经知道了:

对象的单个句柄包含一组属性,您可以使用get()函数读取或使用set()函数进行设置。因此,例如,我想在GUI中出于某种原因更改startButton的文本。

set(handles.startButton,'String','Something Other Than Start');

您可能只想在代码中设置一个断点(可能是按下按钮)并使用句柄结构。在各种对象上运行get()命令以了解其属性。

现在,句柄结构包含GUI对象的所有... umm ...句柄以及可能方便您存储的任何自定义项目。大多数GUI回调会自动传递handle struct,因此您可以轻松访问GUI的所有部分。

实施例。 'startButton'回调自动传递handles。所以我可以通过handles.timer轻松访问计时器对象。

这使我将自定义内容粘贴到handles中。在open函数中,我向句柄结构handles.timerhandles.plot添加了一个新项,因为我知道它们在其他回调中很有用(比如按下按钮和timerFcn回调)。

但是,要永久存储这些东西,您需要使用'guidata'功能。此函数基本上存储修改后的handles结构或根据您调用它的方式检索handles的副本。因此,open函数中的以下行是将修改后的句柄结构(添加.timer和.plot)存储到主GUI中。

guidata(hObject,handles);

基本上,只要您在handles中添加内容,就应该使用该行来永久更改内容。

现在调用它的另一种方法是:

handles = guidata(hObject); %hObject can be any handle who is a child of the main GUI.

这将检索GUI的句柄结构。

最后handles.output = hObject只是启动GUI时的默认输出。如果你通过Matlab的命令行调用你的GUI,就像这个h = myGUI;一样,它应该返回GUI的句柄。

答案 1 :(得分:1)

您需要使用timer object。将回调设置为更新图表的函数。

答案 2 :(得分:1)

查看Making Graphs Responsive with Data Linking linkdata命令。

  

如果多个图中的图中出现相同的变量,则可以   将任何图表链接到变量。您可以使用链接图   音乐会与数字刷新标记图表,但也在他们的   拥有。链接图可以让你

     
      
  • 使图表响应基础工作区或函数
  • 中变量的变化   
  • 在“变量编辑器”和“命令行”中更改变量时,使图形响应
  •   
  • 通过数据刷牙修改变量,一次影响它们的不同图形表示
  •   
  • 为调试目的创建图形“监视窗口”
  •   
     

如果使用MATLAB语言编程,观察窗口非常有用。对于   例如,在细化数据处理算法时要逐步完成   你的代码,你可以看到图表响应变量的变化   函数执行语句。

我在下面看到了一个快速而肮脏的测试,我不确定它如何在GUI中与函数一起工作但是可以做到这一点。

注1:我必须在子程序中添加一个断点,它修改全局y以实际看到图自动更新。如果数据快速变化,您可能需要一些drawow,pause或timer的组合。

function testLinking()
global x y
%Links failed if the global did not also exist in the base workspace
evalin('base','global x y');
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);

h = plot(x,y,'ydatasource','y','xdatasource','x');
linkdata on
testSub

function testSub()
%Test to see if a sub can make a linked global refresh
global x y
for i = 1:10
    %This should automatically update the plot.
    y = sin(x+i/10); 
end

编辑:根据你的函数结构的不同,可能有很多方法可以使用全局变量......但是我没有时间深入研究它。

答案 3 :(得分:0)

您可以在执行绘图功能的串行对象上添加回调。您必须将回调附加到对象上的“BytesAvailableFcn”事件(有关com对象属性的更多详细信息,请参阅this。)

基本上,当com端口上有可用的字节时,您指示matlab运行特定的功能。在您的情况下,它将是更新GUI的功能。如果您需要先处理传入的数据,那么您的回调函数将首先执行信号处理,然后执行绘图命令。