【问题标题】:Call Argument into other function Octave GNU?将参数调用到其他函数 Octave GNU?
【发布时间】:2025-12-11 09:25:01
【问题描述】:

我将 Octave GNU 用于 GUI Excel 数据。 我想问你们如何在另一个函数中调用已定义的参数。 这是我的代码。

%%First Function = pushbutton_Callback

function pushbutton_Callback(hObject, eventdata, handles)
fileName = uigetfile('*.xlsx')%%excel data import

handles.fileName=fileName;

guidata(hObject, handles)

endfunction

%%Second Function = popupmenuX_Callback

function popupmenuX_Callback(hObject, eventdata, handles)
fileName = fileName @pushbutton_Callback; 
printf ("in popupmenuX_Callback, calling pushbutton_Callback\n");

%%To nested function to prevent (because in Octave nested function is not accepted), I used subfunction as alternative%%

handles.fileName=fileName; %% This argument fileName I want to bring from first function
[numbers, colNames]=xlsread(fileName); %%read columns of excel data in first function
set(hObject,'string',colNames);
endfunction

如果我这样放置函数,总是会出现这些错误。

>> fileName = V8.xlsx
error: superclass calls can only occur in methods or constructors
error: called from
    popupmenuX_Callback at line 61 column 10

所以我想做的是,我想将第一个函数(pushbutton_Callback)中定义的参数“fileName”带到第二个函数(popupX_callback)。但它不能在第二个函数中定义。 我听说八度音程中的nested function 可以用“foo”、“foobar”或“ex_top”、“ex_a”函数解析。但我无法解决“ex_”函数的问题。那么我是否必须使用“foo”、“foobar”函数将参数调用到其他函数中?

最好的问候!

================================================ ==============================

我用完整的代码编辑了我的问题。 (完整代码如下) 所以我想做的是,就像这个video。但在视频中的 Matlab 中,可以使用 GUIDE 或应用程序设计器制作,但在 Octave 中没有这样的功能。所以作为一个八度初学者,我很难解决这个问题。

%%Versuch
%% Diagramm zeichen
%%============================================================================
close all
clear h
graphics_toolkit qt
pkg load io
%%Uicontrols
%%Graph
h.ax = axes ("position", [0.3 0.25 0.6 0.5]);


%%Title
h.plot_title_label = uicontrol ("style", "text",
                                "units", "normalized",
                                "string", "Versuchsergebnis",
                                "horizontalalignment", "left",
                                "position", [0.03 0.9 0.25 0.08]);
                                  
%% Design for excel data import
    
h.print_pushbutton = uicontrol ("style", "pushbutton",
                                "units", "normalized",
                                "string", "Excel Datei mitbringen",
                                "callback", @pushbutton_Callback,
                                "position", [0.03 0.8 0.3 0.09]);


%% Drawing axis
h.popupmenuX        = uicontrol("Style","popupmenu",
    "units", "normalized",
    "string","X Axis",...
    "callback", @popupmenuX_Callback,
    "Position",[0.7 0.04 0.2 0.05]);
    
h.popupmenuY        = uicontrol("Style","popupmenu",
    "units", "normalized",
    "string","Y Axis",
    "callback",@popupmenuY_Callback,
    "Position",[0.03 0.5 0.2 0.05]);
%%=============================================================================                              
%% Functions
%%=============================================================================

%% 1. Excel Data import
function pushbutton_Callback(hObject, eventdata, handles)
fileName            = uigetfile('*.xlsx')%%excel data import
handles.fileName    = fileName;
guidata(hObject, handles)
endfunction

%% 2. X Axis Information from excel data import

function popupmenuX_Callback(hObject, eventdata, handles)
fileName            = pushbutton_Callback(hObject, eventdata, handles)
%%This code fileName causes error, that 'handles' is not defined.%%
handles.fileName    = fileName; %% This argument fileName I want to bring from first function
[numbers, colNames] = xlsread(fileName); %%read columns of excel data in first function
set(hObject,'string',colNames);
endfunction

%% 3. Y Axis Information from excel data import
function popupmenuY_Callback(hObject, eventdata, handles)
filename            = pushbutton_Callback(hObject, eventdata, handles)
handles.fileName    = fileName;
[numbers, colNames] = xlsread(fileName);
set(hObject,'string',colNames);
endfunction

%%%% Plot the graph
a                   = xlsread (fileName);
xColNum             = get(popupmenuX_Callback,'value');
yColNum             = get(popupmenuY_Callback,'value');
fileName            = handles.fileName;
x                   = a(:,xColNum);
y                   = a(:,yColNum);
h.ax                = plot(x,y);

【问题讨论】:

  • 你对函数和变量的心智模型是错误的。函数中定义的变量仅在该函数运行时存在。在函数结束时,它的所有变量都被销毁。因此,如果您以后需要这些值之一,则必须将其保存在您可以从需要它的地方访问它的地方。哦,你实际上已经这样做了:handles.fileName=fileName; guidata(hObject, handles)。阅读guidata 文档以了解如何读取您的数据。
  • 感谢@Cris 的回答。抱歉,我不明白你的建议不太好,因为我是 Octave 的第一名。你能告诉我我在这个函数和变量中犯了什么样的错误吗?我认为它工作得很好,我的意思是它适用于在第一个函数中导​​入文件名,这就是我所期望的。我已经阅读了有关guidata 的文档,但我仍然无法理解我的问题。

标签: arguments octave nested-function octave-gui


【解决方案1】:

上面是 Tasos 的答案(带有 csv 文件),我将他的答案应用于我的代码,该代码适用于 excel 文件。因为代码xlsread 忽略了这些列,所以用户应该注意这一点。

再次感谢 Tasos!

 pkg load io

% Create the Gui Window which will hold all controls and relevant data.
  GuiWindow = figure()

% An 'axes' object for displaying plots in the Gui Window
  axes ("position", [0.3 0.25 0.6 0.5], 'tag', 'plotarea' );

% Static text element used as a title
  uicontrol ("style", "text", "units", "normalized", "string", "Versuchsergebnis",'ForegroundColor','w','BackgroundColor',[0 0.4470 0.7410],'Fontweight','bold', "horizontalalignment", "center", "position", [0.03 0.9 0.35 0.08] );
                                    
% A button for importing (excel) data
  uicontrol ("style", "pushbutton", "units", "normalized", "string", "Datei(xlsx) mitbringen", "callback", { @pushbutton_Callback, GuiWindow }, "position", [0.03 0.8 0.35 0.09], 'tag', 'button' );

% Popupmenus for selecting appropriate X and Y axis to display in plots
  uicontrol("Style","popupmenu", "units", "normalized", "string","X Axis", "callback", { @popupmenuX_Callback, GuiWindow }, "Position",[0.7 0.04 0.2 0.05], 'tag', 'XAxisMenu' );
  uicontrol("Style","popupmenu", "units", "normalized", "string","Y Axis", "callback", { @popupmenuY_Callback, GuiWindow }, "Position",[0.03 0.5 0.2 0.05], 'tag', 'YAxisMenu' );

  %%=============================================================================                              
  %% Functions (preferably placed in their own files!)
  %%=============================================================================

  function pushbutton_Callback(hObject, eventdata, GuiWindow)

    % Read in data from file, graphically selected by user
      fileName      = uigetfile('*.xlsx');
      [num,txt,raw] = xlsread(fileName);
      header        = raw(1,:);
      Data          = xlsread(fileName);
    % Show fileName
      button   = findobj('tag', 'button');
      set( button, 'string', fileName)
    % Populate the menu items for the X and Y Axis from the csv header
      XAxisMenu = findobj( 'tag', 'XAxisMenu' );
      set( XAxisMenu, 'string', header );

      YAxisMenu = findobj( 'tag', 'YAxisMenu' );
      set( YAxisMenu, 'string', header );

    % Also store headers and data as GuiWindow app data, in case we need them again later.
      setappdata( GuiWindow, 'header', header );
      setappdata( GuiWindow, 'Data'  , Data   );

    % Plot a preliminary plot in the plot area
      XData = Data(:, 1);
      YData = Data(:, 1);
      plot( XData, YData, 'tag', 'plotobject' );          
  endfunction

  %% 2. X Axis Information from excel data import
  function popupmenuX_Callback( hObject, eventdata, GuiWindow )
      Axes      = findobj( 'tag', 'plotarea' );
      Selection = get( hObject, 'value' );
      XData     = [ getappdata( GuiWindow, 'Data' )( :, Selection ) ];
      PlotObj   = findobj( 'tag', 'plotobject' );
      set( PlotObj, 'xdata', XData )
  endfunction

  %% 3. Y Axis Information from excel data import
  function popupmenuY_Callback( hObject, eventdata, GuiWindow )
      Axes      = findobj( 'tag', 'plotarea' );
      Selection = get( hObject, 'value' );
      YData     = [ getappdata( GuiWindow, 'Data' )( :, Selection ) ];
      PlotObj   = findobj( 'tag', 'plotobject' );
      set( PlotObj, 'ydata', YData )
  endfunction

【讨论】:

  • 不客气!如果您对您的答案感到满意,请将其标记为正确;这会将问题标记为在主屏幕中已回答(在网站上搜索时会以不同方式处理)。
【解决方案2】:

允许加载 .csv 文件并根据 csv 标题填充两个弹出菜单的 GUI 示例。

data.csv 文件示例:

Col1, Col2, Col3
1,    2,    3
2,    4,    8
3,    8,    9

示例 myscript.m

  pkg load io

% Create the Gui Window which will hold all controls and relevant data.
  GuiWindow = figure()

% An 'axes' object for displaying plots in the Gui Window
  axes ("position", [0.3 0.25 0.6 0.5], 'tag', 'plotarea' );

% Static text element used as a title
  uicontrol ("style", "text", "units", "normalized", "string", "Fur Zoo Hair Geb knees.", "horizontalalignment", "left", "position", [0.03 0.9 0.3 0.08] );
                                    
% A button for importing (excel) data
  uicontrol ("style", "pushbutton", "units", "normalized", "string", "CSV Dat Eye Meat Bringen", "callback", { @pushbutton_Callback, GuiWindow }, "position", [0.03 0.8 0.35 0.09], 'tag', 'button' );

% Popupmenus for selecting appropriate X and Y axis to display in plots
  uicontrol("Style","popupmenu", "units", "normalized", "string","X Axis", "callback", { @popupmenuX_Callback, GuiWindow }, "Position",[0.7 0.04 0.2 0.05], 'tag', 'XAxisMenu' );
  uicontrol("Style","popupmenu", "units", "normalized", "string","Y Axis", "callback", { @popupmenuY_Callback, GuiWindow }, "Position",[0.03 0.5 0.2 0.05], 'tag', 'YAxisMenu' );

  %%=============================================================================                              
  %% Functions (preferably placed in their own files!)
  %%=============================================================================

  function pushbutton_Callback(hObject, eventdata, GuiWindow)

    % Read in data from file, graphically selected by user
      fileName = uigetfile('*.csv');
      CellCsv  = csv2cell( fileName );
      Header   = CellCsv(1, :);
      Data     = CellCsv(2:end, :);

    % Populate the menu items for the X and Y Axis from the csv header
      XAxisMenu = findobj( 'tag', 'XAxisMenu' );
      set( XAxisMenu, 'string', Header );

      YAxisMenu = findobj( 'tag', 'YAxisMenu' );
      set( YAxisMenu, 'string', Header );

    % Also store headers and data as GuiWindow app data, in case we need them again later.
      setappdata( GuiWindow, 'Header', Header );
      setappdata( GuiWindow, 'Data'  , Data   );

    % Plot a preliminary plot in the plot area
      XData = [Data{:, 1}];
      YData = [Data{:, 1}];
      plot( XData, YData, 'bo-', 'tag', 'plotobject' );          
  endfunction

  %% 2. X Axis Information from excel data import
  function popupmenuX_Callback( hObject, eventdata, GuiWindow )
      Axes      = findobj( 'tag', 'plotarea' );
      Selection = get( hObject, 'value' );
      XData     = [ getappdata( GuiWindow, 'Data' ){ :, Selection } ];
      PlotObj   = findobj( 'tag', 'plotobject' );
      set( PlotObj, 'xdata', XData )
  endfunction

  %% 3. Y Axis Information from excel data import
  function popupmenuY_Callback( hObject, eventdata, GuiWindow )
      Axes      = findobj( 'tag', 'plotarea' );
      Selection = get( hObject, 'value' );
      YData     = [ getappdata( GuiWindow, 'Data' ){ :, Selection } ];
      PlotObj   = findobj( 'tag', 'plotobject' );
      set( PlotObj, 'ydata', YData )
  endfunction

这演示了在回调中访问其他图形对象的两种方法。一种是提供一个对象作为参数(例如 GuiWindow),另一种是通过findobj 函数提供可用于识别对象的“标签”。

请注意,我只将数据存储在 GuiWindow 对象中,而不是存储到每个单独的图形对象(如按钮等)。另外,我更喜欢 setappdata,因为它允许以单独的名称存储多个数据(而 guidata 只存储单个对象,尽管这可以是一个结构)。

【讨论】:

  • 非常感谢@Tasos!这就是我想要的。我将您的代码应用于我的代码,该代码适用于 excel 文件。对于需要导入excel文件的人,我会把它放在我的答案中。我从来没有意识到,有像tagfindobj 或类似的代码。真的非常感谢!
【解决方案3】:

线

fileName = fileName @pushbutton_Callback; 

没有按照你的想法去做。

解释背景有点复杂,但基本上在matlab中,使用classdef关键字创建的新型类也​​允许继承,允许您调用“父”类(或“超类”)的方法通过methodname@parentclassname(args) 语法。 Octave 也将此系统移植到了 octave,以实现 matlab 兼容性。您实际上得到的错误表明您正在尝试在没有意义的上下文中调用超类方法(这是真的,因为您不在 classdef 块内)。

这解释了为什么会出现该错误。

现在,就您尝试要做的事情而言,我认为您基本上只是想从您的popupmenuX_Callback 中调用pushbutton_Callback 函数,对吧?因此,只需使用适当的参数即可,例如:

filename            = pushbutton_Callback(hObject, eventdata, handles)
[numbers, colNames] = xlsread(fileName);

PS。我建议您始终在函数内缩进代码。它看起来更清晰,有助于捕捉错误!

【讨论】:

  • 感谢您的建议@Tasos。因为我是 Octave 的新手,所以我不知道我能做什么。根据您提到的内容,我尝试将“classdef”放入我的代码中。但它不起作用并且总是出现解析错误。 link 在这里我上传了我的错误。如果您也可以阅读此问题,我将不胜感激。谢谢塔索斯!!
  • 对。忘记classdef,忽略我回答的第一部分。我只是想解释为什么你会看到那个特定的错误信息。对不起,我不是故意要混淆你的。只关注最后一段。
  • 基本上把fileName = fileName @pushbutton_Callback;替换成filename = pushbutton_Callback(hObject, eventdata, handles);
  • 另外,听起来你有更基本的问题,关于什么是函数句柄,如何使用特定签名的函数句柄作为回调,以及如何使用它来制作 gui 程序。这超出了 * 答案所能涵盖的范围......以this simple gui program 为例,让您开始在八度音程上进行 gui 编程。
  • 再次感谢 Tasos,将 fileName = fileName @pushbutton_Callback; 替换为 filename = pushbutton_Callback(hObject, eventdata, handles);我也尝试过,但后来,句柄似乎未定义。 >> fileName = V8.xlsx error: 'handles' undefined near line 62, column 62 error: called from popupmenuX_Callback at line 62 column 21 .